@utsp/render 0.16.1 → 0.17.0-nightly.20260120215017.712755a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/2d/index.cjs CHANGED
@@ -1,11 +1,11 @@
1
- "use strict";var W=Object.defineProperty;var X=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var N=(g,t,e)=>t in g?W(g,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):g[t]=e;var f=(g,t)=>W(g,"name",{value:t,configurable:!0});var _=(g,t)=>{for(var e in t)W(g,e,{get:t[e],enumerable:!0})},j=(g,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Y(t))!P.call(g,s)&&s!==e&&W(g,s,{get:()=>t[s],enumerable:!(i=X(t,s))||i.enumerable});return g};var q=g=>j(W({},"__esModule",{value:!0}),g);var h=(g,t,e)=>(N(g,typeof t!="symbol"?t+"":t,e),e);var Z={};_(Z,{BitmapFontAtlas:()=>M,DEFAULT_PALETTE:()=>I,GridOverlay:()=>y,ImageFontAtlas:()=>H,ScalingMode:()=>O.ScalingMode,Terminal2D:()=>A,colorToPaletteIndex:()=>L,getAtlasColumns:()=>E,getCharGridPosition:()=>R,getMaxCharCode:()=>D,paletteIndexToColor:()=>z});module.exports=q(Z);var B=class B{constructor(t,e,i,s,n){h(this,"atlases");h(this,"charMap");h(this,"baseCharWidth");h(this,"baseCharHeight");h(this,"baseCellWidth");h(this,"baseCellHeight");h(this,"atlasColumns",16);h(this,"font");h(this,"SCALES",[1,2,4,8]);h(this,"colorCache",new Map);h(this,"MAX_CACHE_SIZE",512);this.font=t,this.baseCharWidth=e,this.baseCharHeight=i,this.baseCellWidth=s??e,this.baseCellHeight=n??i,this.charMap=new Map,this.atlases=new Map,this.generateAtlases()}generateAtlases(){this.atlasColumns=16;let t=0;for(let[e,i]of this.font){let s=t%this.atlasColumns,n=Math.floor(t/this.atlasColumns);this.charMap.set(e,{x:s*this.baseCharWidth,y:n*this.baseCharHeight});for(let r of this.SCALES){let a=this.getOrCreateAtlas(r),l=s*a.charWidth,o=n*a.charHeight;this.renderBitmapToAtlas(a,i,l,o)}t++}}getOrCreateAtlas(t){let e=this.atlases.get(t);if(!e){let i=this.baseCharWidth*t,s=this.baseCharHeight*t,r=Math.ceil(256/this.atlasColumns),a=document.createElement("canvas");a.width=this.atlasColumns*i,a.height=r*s;let l=a.getContext("2d",{alpha:!0,willReadFrequently:!1});if(!l)throw new Error(`Impossible de cr\xE9er le contexte 2D pour l'atlas ${t}x`);l.imageSmoothingEnabled=!1,e={canvas:a,ctx:l,scale:t,charWidth:i,charHeight:s},this.atlases.set(t,e)}return e}renderBitmapToAtlas(t,e,i,s){let n=t.scale,r=t.ctx;r.fillStyle="#ffffff";for(let a=0;a<Math.min(e.length,this.baseCharHeight);a++){let l=e[a];for(let o=0;o<this.baseCharWidth;o++){let c=1<<7-o;l&c&&r.fillRect(i+o*n,s+a*n,n,n)}}}drawChar(t,e,i,s,n,r,a){let l=this.charMap.get(e);if(!l)return;let o=`${e}:${a}`,c=this.colorCache.get(o);if(c)c.lastUsed=performance.now();else{let p=this.createColoredGlyph(e,a,l);if(!p)return;c={canvas:p,lastUsed:performance.now()},this.colorCache.set(o,c),this.colorCache.size>this.MAX_CACHE_SIZE&&this.evictLRU()}let d=n/this.baseCellWidth,m=r/this.baseCellHeight,u=(this.baseCellWidth-this.baseCharWidth)/2*d,w=(this.baseCellHeight-this.baseCharHeight)/2*m,b=this.baseCharWidth*d,C=this.baseCharHeight*m;t.drawImage(c.canvas,i+u,s+w,b,C)}createColoredGlyph(t,e,i){let s=this.atlases.get(1);if(!s)return null;let n=s.ctx.getImageData(i.x,i.y,this.baseCharWidth,this.baseCharHeight),r=n.data,a=this.hexToRgb(e);for(let c=0;c<r.length;c+=4)r[c+3]>0&&(r[c]=a.r,r[c+1]=a.g,r[c+2]=a.b);let l=document.createElement("canvas");l.width=this.baseCharWidth,l.height=this.baseCharHeight;let o=l.getContext("2d",{alpha:!0});return o?(o.imageSmoothingEnabled=!1,o.putImageData(n,0,0),l):null}hexToRgb(t){if(t.startsWith("#")){let n=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;t=t.replace(n,(a,l,o,c)=>l+l+o+o+c+c);let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);return r?{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16)}:{r:255,g:255,b:255}}let e=/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*[\d.]+)?\)/.exec(t);if(e)return{r:parseInt(e[1],10),g:parseInt(e[2],10),b:parseInt(e[3],10)};let s={white:[255,255,255],black:[0,0,0],red:[255,0,0],green:[0,255,0],blue:[0,0,255],yellow:[255,255,0],cyan:[0,255,255],magenta:[255,0,255]}[t.toLowerCase()];return s?{r:s[0],g:s[1],b:s[2]}:{r:255,g:255,b:255}}evictLRU(){let t=null,e=1/0;for(let[i,s]of this.colorCache)s.lastUsed<e&&(e=s.lastUsed,t=i);if(t){let i=this.colorCache.get(t);i&&(i.canvas.width=0,i.canvas.height=0),this.colorCache.delete(t)}}getAtlasCanvas(t=1){return this.atlases.get(t)?.canvas}getAllAtlases(){return this.atlases}getCharDimensions(){return{width:this.baseCharWidth,height:this.baseCharHeight}}getCharCount(){return this.charMap.size}hasChar(t){return this.charMap.has(t)}getAtlasDimensions(t=1){let e=this.atlases.get(t);if(e)return{width:e.canvas.width,height:e.canvas.height}}toDataURL(t=1,e="image/png"){return this.atlases.get(t)?.canvas.toDataURL(e)}getCacheStats(){return{size:this.colorCache.size,maxSize:this.MAX_CACHE_SIZE}}clearCache(){for(let t of this.colorCache.values())t.canvas.width=0,t.canvas.height=0;this.colorCache.clear()}destroy(){this.charMap.clear();for(let t of this.atlases.values())t.canvas.width=0,t.canvas.height=0;this.atlases.clear(),this.clearCache()}};f(B,"BitmapFontAtlas");var M=B;function E(g){return Math.sqrt(g)*16}f(E,"getAtlasColumns");function D(g){return g*256-1}f(D,"getMaxCharCode");function R(g,t){let e=Math.floor(g/256),i=g%256,s=Math.sqrt(t),n=e%s,r=Math.floor(e/s),a=i%16,l=Math.floor(i/16);return{col:n*16+a,row:r*16+l}}f(R,"getCharGridPosition");var T=class T{constructor(t){h(this,"atlasCanvas",null);h(this,"atlasCtx",null);h(this,"atlasImage",null);h(this,"glyphWidth");h(this,"glyphHeight");h(this,"cellWidth");h(this,"cellHeight");h(this,"atlasBlocks");h(this,"atlasColumns");h(this,"maxCharCode");h(this,"isLoaded",!1);h(this,"colorCache",new Map);h(this,"MAX_CACHE_SIZE",1024);this.glyphWidth=t.glyphWidth,this.glyphHeight=t.glyphHeight,this.cellWidth=t.cellWidth??t.glyphWidth,this.cellHeight=t.cellHeight??t.glyphHeight,this.atlasBlocks=t.atlasBlocks,this.atlasColumns=E(t.atlasBlocks),this.maxCharCode=D(t.atlasBlocks)}async loadFromPNG(t){return new Promise((e,i)=>{let s=new Uint8Array(t),n=new Blob([s],{type:"image/png"}),r=URL.createObjectURL(n),a=new Image;a.onload=()=>{URL.revokeObjectURL(r);let l=this.atlasColumns*this.glyphWidth,o=this.atlasColumns*this.glyphHeight;if((a.width!==l||a.height!==o)&&console.warn(`ImageFontAtlas: Image size ${a.width}\xD7${a.height} doesn't match expected ${l}\xD7${o} for ${this.atlasBlocks} block(s) with ${this.glyphWidth}\xD7${this.glyphHeight} glyphs`),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=a.width,this.atlasCanvas.height=a.height,this.atlasCtx=this.atlasCanvas.getContext("2d",{alpha:!0,willReadFrequently:!0}),!this.atlasCtx){i(new Error("Failed to create 2D context for atlas"));return}this.atlasCtx.imageSmoothingEnabled=!1,this.atlasCtx.drawImage(a,0,0),this.atlasImage=a,this.isLoaded=!0,e()},a.onerror=()=>{URL.revokeObjectURL(r),i(new Error("Failed to load PNG image for atlas"))},a.src=r})}isReady(){return this.isLoaded}getGlyphPosition(t){if(t<0||t>this.maxCharCode)return null;let{col:e,row:i}=R(t,this.atlasBlocks);return{x:e*this.glyphWidth,y:i*this.glyphHeight}}getCharUV(t){if(t<0||t>this.maxCharCode)return null;let{col:e,row:i}=R(t,this.atlasBlocks),s=e/this.atlasColumns,n=i/this.atlasColumns,r=(e+1)/this.atlasColumns,a=(i+1)/this.atlasColumns;return{u1:s,v1:n,u2:r,v2:a}}drawChar(t,e,i,s,n,r,a){if(!this.isLoaded||!this.atlasCanvas)return;let l=this.getGlyphPosition(e);if(!l)return;let o=`${e}:${a}`,c=this.colorCache.get(o);if(c)c.lastUsed=performance.now();else{let m=this.createColoredGlyph(e,a,l);if(!m)return;c={canvas:m,lastUsed:performance.now()},this.colorCache.set(o,c),this.colorCache.size>this.MAX_CACHE_SIZE&&this.evictLRU()}if(t.imageSmoothingEnabled=!1,n===this.cellWidth&&r===this.cellHeight){let m=Math.floor((this.cellWidth-this.glyphWidth)/2),u=Math.floor((this.cellHeight-this.glyphHeight)/2);t.drawImage(c.canvas,Math.floor(i)+m,Math.floor(s)+u)}else{let m=n/this.cellWidth,u=r/this.cellHeight,w=Math.floor((this.cellWidth-this.glyphWidth)/2*m),b=Math.floor((this.cellHeight-this.glyphHeight)/2*u),C=Math.ceil(this.glyphWidth*m),p=Math.ceil(this.glyphHeight*u);t.drawImage(c.canvas,Math.floor(i)+w,Math.floor(s)+b,C,p)}}createColoredGlyph(t,e,i){if(!this.atlasCtx)return null;let s=this.atlasCtx.getImageData(i.x,i.y,this.glyphWidth,this.glyphHeight),n=s.data,r=this.parseColor(e);for(let o=0;o<n.length;o+=4)n[o+3]>0&&(n[o]=r.r,n[o+1]=r.g,n[o+2]=r.b);let a=document.createElement("canvas");a.width=this.glyphWidth,a.height=this.glyphHeight;let l=a.getContext("2d",{alpha:!0});return l?(l.putImageData(s,0,0),a):null}parseColor(t){if(t.startsWith("#")){let i=t.slice(1);return i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),{r:parseInt(i.slice(0,2),16),g:parseInt(i.slice(2,4),16),b:parseInt(i.slice(4,6),16)}}let e=/rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(t);return e?{r:parseInt(e[1],10),g:parseInt(e[2],10),b:parseInt(e[3],10)}:{r:255,g:255,b:255}}evictLRU(){let t=null,e=1/0;for(let[i,s]of this.colorCache)s.lastUsed<e&&(e=s.lastUsed,t=i);if(t){let i=this.colorCache.get(t);i&&(i.canvas.width=0,i.canvas.height=0),this.colorCache.delete(t)}}getAtlasCanvas(){return this.atlasCanvas}getAtlasImage(){return this.atlasImage}getConfig(){return{glyphWidth:this.glyphWidth,glyphHeight:this.glyphHeight,cellWidth:this.cellWidth,cellHeight:this.cellHeight,atlasBlocks:this.atlasBlocks}}getGlyphDimensions(){return{width:this.glyphWidth,height:this.glyphHeight}}getCellDimensions(){return{width:this.cellWidth,height:this.cellHeight}}getAtlasDimensions(){return{width:this.atlasColumns*this.glyphWidth,height:this.atlasColumns*this.glyphHeight}}getAtlasColumns(){return this.atlasColumns}getMaxCharCode(){return this.maxCharCode}isValidCharCode(t){return t>=0&&t<=this.maxCharCode}clearCache(){for(let t of this.colorCache.values())t.canvas.width=0,t.canvas.height=0;this.colorCache.clear()}getCacheStats(){return{size:this.colorCache.size,maxSize:this.MAX_CACHE_SIZE}}destroy(){this.clearCache(),this.atlasCanvas&&(this.atlasCanvas.width=0,this.atlasCanvas.height=0,this.atlasCanvas=null),this.atlasCtx=null,this.atlasImage=null,this.isLoaded=!1}};f(T,"ImageFontAtlas");var H=T;var G=class G{constructor(t,e){h(this,"canvas");h(this,"ctx");h(this,"container");h(this,"cols",0);h(this,"rows",0);h(this,"cellWidth",0);h(this,"cellHeight",0);h(this,"offsetX",0);h(this,"offsetY",0);h(this,"strokeColor","rgba(80, 80, 80, 0.4)");h(this,"lineWidth",1);this.container=t,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let i=e?.zIndex??10;this.canvas.style.cssText=`
1
+ "use strict";var b=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var O=(d,t,e)=>t in d?b(d,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):d[t]=e;var u=(d,t)=>b(d,"name",{value:t,configurable:!0});var F=(d,t)=>{for(var e in t)b(d,e,{get:t[e],enumerable:!0})},U=(d,t,e,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of z(t))!L.call(d,s)&&s!==e&&b(d,s,{get:()=>t[s],enumerable:!(i=T(t,s))||i.enumerable});return d};var P=d=>U(b({},"__esModule",{value:!0}),d);var h=(d,t,e)=>(O(d,typeof t!="symbol"?t+"":t,e),e);var $={};F($,{DEFAULT_PALETTE:()=>H,GridOverlay:()=>v,ImageFontAtlas:()=>C,ScalingMode:()=>k.ScalingMode,Terminal2D:()=>M,colorToPaletteIndex:()=>A,getAtlasColumns:()=>x,getCharGridPosition:()=>w,getMaxCharCode:()=>y,paletteIndexToColor:()=>G});module.exports=P($);function x(d){return Math.sqrt(d)*16}u(x,"getAtlasColumns");function y(d){return d*256-1}u(y,"getMaxCharCode");function w(d,t){let e=Math.floor(d/256),i=d%256,s=Math.sqrt(t),n=e%s,l=Math.floor(e/s),r=i%16,a=Math.floor(i/16);return{col:n*16+r,row:l*16+a}}u(w,"getCharGridPosition");var W=class W{constructor(t){h(this,"atlasCanvas",null);h(this,"atlasCtx",null);h(this,"atlasImage",null);h(this,"glyphWidth");h(this,"glyphHeight");h(this,"cellWidth");h(this,"cellHeight");h(this,"atlasBlocks");h(this,"atlasColumns");h(this,"maxCharCode");h(this,"isLoaded",!1);h(this,"colorCache",new Map);h(this,"MAX_CACHE_SIZE",1024);this.glyphWidth=t.glyphWidth,this.glyphHeight=t.glyphHeight,this.cellWidth=t.cellWidth??t.glyphWidth,this.cellHeight=t.cellHeight??t.glyphHeight,this.atlasBlocks=t.atlasBlocks,this.atlasColumns=x(t.atlasBlocks),this.maxCharCode=y(t.atlasBlocks)}getCanvas(){return this.atlasCanvas}getGlyphWidth(){return this.glyphWidth}getGlyphHeight(){return this.glyphHeight}prepare(){let t=this.atlasColumns*this.glyphWidth,e=this.atlasColumns*this.glyphHeight;this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=t,this.atlasCanvas.height=e,this.atlasCtx=this.atlasCanvas.getContext("2d",{alpha:!0,willReadFrequently:!0}),this.atlasCtx&&(this.atlasCtx.imageSmoothingEnabled=!1,this.atlasCtx.clearRect(0,0,t,e)),this.isLoaded=!0}async loadBlock(t,e){return(!this.atlasCanvas||!this.atlasCtx)&&this.prepare(),new Promise((i,s)=>{let n=new Uint8Array(e),l=new Blob([n],{type:"image/png"}),r=URL.createObjectURL(l),a=new Image;a.onload=()=>{URL.revokeObjectURL(r);let o=Math.sqrt(this.atlasBlocks),c=t%o,g=Math.floor(t/o),m=c*16*this.glyphWidth,f=g*16*this.glyphHeight;this.atlasCtx.drawImage(a,m,f),this.colorCache.clear(),i()},a.onerror=()=>{URL.revokeObjectURL(r),s(new Error(`Failed to load PNG for block ${t}`))},a.src=r})}async loadFromPNG(t){return new Promise((e,i)=>{let s=new Uint8Array(t),n=new Blob([s],{type:"image/png"}),l=URL.createObjectURL(n),r=new Image;r.onload=()=>{URL.revokeObjectURL(l);let a=this.atlasColumns*this.glyphWidth,o=this.atlasColumns*this.glyphHeight;if((r.width!==a||r.height!==o)&&console.warn(`ImageFontAtlas: Image size ${r.width}\xD7${r.height} doesn't match expected ${a}\xD7${o} for ${this.atlasBlocks} block(s) with ${this.glyphWidth}\xD7${this.glyphHeight} glyphs`),this.atlasCanvas=document.createElement("canvas"),this.atlasCanvas.width=r.width,this.atlasCanvas.height=r.height,this.atlasCtx=this.atlasCanvas.getContext("2d",{alpha:!0,willReadFrequently:!0}),!this.atlasCtx){i(new Error("Failed to create 2D context for atlas"));return}this.atlasCtx.imageSmoothingEnabled=!1,this.atlasCtx.drawImage(r,0,0),this.atlasImage=r,this.isLoaded=!0,e()},r.onerror=()=>{URL.revokeObjectURL(l),i(new Error("Failed to load PNG image for atlas"))},r.src=l})}isReady(){return this.isLoaded}getGlyphPosition(t){if(t<0||t>this.maxCharCode)return null;let{col:e,row:i}=w(t,this.atlasBlocks);return{x:e*this.glyphWidth,y:i*this.glyphHeight}}getCharUV(t){if(t<0||t>this.maxCharCode)return null;let{col:e,row:i}=w(t,this.atlasBlocks),s=e/this.atlasColumns,n=i/this.atlasColumns,l=(e+1)/this.atlasColumns,r=(i+1)/this.atlasColumns;return{u1:s,v1:n,u2:l,v2:r}}drawChar(t,e,i,s,n,l,r){if(!this.isLoaded||!this.atlasCanvas)return;let a=this.getGlyphPosition(e);if(!a)return;let o=`${e}:${r}`,c=this.colorCache.get(o);if(c)c.lastUsed=performance.now();else{let m=this.createColoredGlyph(e,r,a);if(!m)return;c={canvas:m,lastUsed:performance.now()},this.colorCache.set(o,c),this.colorCache.size>this.MAX_CACHE_SIZE&&this.evictLRU()}if(t.imageSmoothingEnabled=!1,n===this.cellWidth&&l===this.cellHeight){let m=Math.floor((this.cellWidth-this.glyphWidth)/2),f=Math.floor((this.cellHeight-this.glyphHeight)/2);t.drawImage(c.canvas,Math.floor(i)+m,Math.floor(s)+f)}else{let m=n/this.cellWidth,f=l/this.cellHeight,D=Math.floor((this.cellWidth-this.glyphWidth)/2*m),B=Math.floor((this.cellHeight-this.glyphHeight)/2*f),S=Math.ceil(this.glyphWidth*m),I=Math.ceil(this.glyphHeight*f);t.drawImage(c.canvas,Math.floor(i)+D,Math.floor(s)+B,S,I)}}createColoredGlyph(t,e,i){if(!this.atlasCtx)return null;let s=this.atlasCtx.getImageData(i.x,i.y,this.glyphWidth,this.glyphHeight),n=s.data,l=this.parseColor(e);for(let o=0;o<n.length;o+=4)n[o+3]>0&&(n[o]=n[o]*l.r/255,n[o+1]=n[o+1]*l.g/255,n[o+2]=n[o+2]*l.b/255);let r=document.createElement("canvas");r.width=this.glyphWidth,r.height=this.glyphHeight;let a=r.getContext("2d",{alpha:!0});return a?(a.putImageData(s,0,0),r):null}parseColor(t){if(t.startsWith("#")){let i=t.slice(1);return i.length===3&&(i=i[0]+i[0]+i[1]+i[1]+i[2]+i[2]),{r:parseInt(i.slice(0,2),16),g:parseInt(i.slice(2,4),16),b:parseInt(i.slice(4,6),16)}}let e=/rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(t);return e?{r:parseInt(e[1],10),g:parseInt(e[2],10),b:parseInt(e[3],10)}:{r:255,g:255,b:255}}evictLRU(){let t=null,e=1/0;for(let[i,s]of this.colorCache)s.lastUsed<e&&(e=s.lastUsed,t=i);if(t){let i=this.colorCache.get(t);i&&(i.canvas.width=0,i.canvas.height=0),this.colorCache.delete(t)}}getAtlasCanvas(){return this.atlasCanvas}getAtlasImage(){return this.atlasImage}getConfig(){return{glyphWidth:this.glyphWidth,glyphHeight:this.glyphHeight,cellWidth:this.cellWidth,cellHeight:this.cellHeight,atlasBlocks:this.atlasBlocks}}getGlyphDimensions(){return{width:this.glyphWidth,height:this.glyphHeight}}getCellDimensions(){return{width:this.cellWidth,height:this.cellHeight}}getAtlasDimensions(){return{width:this.atlasColumns*this.glyphWidth,height:this.atlasColumns*this.glyphHeight}}getAtlasColumns(){return this.atlasColumns}getMaxCharCode(){return this.maxCharCode}isValidCharCode(t){return t>=0&&t<=this.maxCharCode}clearCache(){for(let t of this.colorCache.values())t.canvas.width=0,t.canvas.height=0;this.colorCache.clear()}getCacheStats(){return{size:this.colorCache.size,maxSize:this.MAX_CACHE_SIZE}}destroy(){this.clearCache(),this.atlasCanvas&&(this.atlasCanvas.width=0,this.atlasCanvas.height=0,this.atlasCanvas=null),this.atlasCtx=null,this.atlasImage=null,this.isLoaded=!1}};u(W,"ImageFontAtlas");var C=W;var R=class R{constructor(t,e){h(this,"canvas");h(this,"ctx");h(this,"container");h(this,"cols",0);h(this,"rows",0);h(this,"cellWidth",0);h(this,"cellHeight",0);h(this,"offsetX",0);h(this,"offsetY",0);h(this,"strokeColor","rgba(80, 80, 80, 0.4)");h(this,"lineWidth",1);this.container=t,this.canvas=document.createElement("canvas"),this.canvas.className="grid-overlay-canvas";let i=e?.zIndex??10;this.canvas.style.cssText=`
2
2
  display: block !important;
3
3
  position: absolute !important;
4
4
  pointer-events: none !important;
5
5
  image-rendering: pixelated !important;
6
6
  image-rendering: crisp-edges !important;
7
7
  z-index: ${i} !important;
8
- `,this.container.appendChild(this.canvas);let s=this.canvas.getContext("2d");if(!s)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=s,e&&(e.strokeColor&&(this.strokeColor=e.strokeColor),e.lineWidth!==void 0&&(this.lineWidth=e.lineWidth))}setDimensions(t,e,i,s,n=0,r=0){this.cols=t,this.rows=e,this.cellWidth=i,this.cellHeight=s,this.offsetX=n,this.offsetY=r}setCanvasSize(t,e){this.canvas.width=t,this.canvas.height=e,this.ctx.setTransform(1,0,0,1,0,0)}setStyle(t){t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth)}setTransform(t,e,i,s,n){let r=s.left-n.left,a=s.top-n.top,l=s.width,o=s.height;(this.canvas.width!==l||this.canvas.height!==o)&&(this.canvas.width=l,this.canvas.height=o);let c=this.canvas.style;c.width=`${l}px`,c.height=`${o}px`,c.left=`${r}px`,c.top=`${a}px`}render(){if(!this.ctx)return;let t=this.cols*this.cellWidth,e=this.rows*this.cellHeight,i=t>0?this.canvas.width/t:1,s=e>0?this.canvas.height/e:1,n=Math.min(i,s),r=this.cellWidth*n,a=this.cellHeight*n,l=this.cols*r,o=this.rows*a,c=this.offsetX*n,d=this.offsetY*n;if(!(l===0||o===0)){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.strokeStyle=this.strokeColor,this.ctx.lineWidth=Math.max(1,this.lineWidth*n),this.ctx.beginPath();for(let m=0;m<=this.cols;m++){let u=c+m*r+.5;this.ctx.moveTo(u,d),this.ctx.lineTo(u,d+o)}for(let m=0;m<=this.rows;m++){let u=d+m*a+.5;this.ctx.moveTo(c,u),this.ctx.lineTo(c+l,u)}this.ctx.stroke()}}update(t,e,i,s,n,r,a=0,l=0){this.setDimensions(t,e,i,s,a,l),this.setCanvasSize(n,r),this.render()}setVisible(t){this.canvas.style.display=t?"block":"none"}destroy(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}};f(G,"GridOverlay");var y=G;var v=require("@utsp/types");var k=class k{constructor(t,e={}){h(this,"containerDiv");h(this,"canvas");h(this,"ctx");h(this,"parentElement");h(this,"cells");h(this,"cols",0);h(this,"rows",0);h(this,"fontSize");h(this,"fontFamily");h(this,"defaultFgColor");h(this,"defaultBgColor");h(this,"canvasBgColor");h(this,"cellWidth");h(this,"cellHeight");h(this,"offsetX",0);h(this,"offsetY",0);h(this,"fontType","web");h(this,"bitmapFont");h(this,"bitmapAtlas");h(this,"imageAtlas");h(this,"bitmapCharWidth",8);h(this,"bitmapCharHeight",8);h(this,"showDebugGrid");h(this,"debugGridColor");h(this,"gridOverlay");h(this,"fixedGridMode");h(this,"fixedCols");h(this,"fixedRows");h(this,"cellAspectRatio");h(this,"resizeObserver");h(this,"imageDataBuffer");h(this,"useImageDataRendering",!1);h(this,"paletteCache");h(this,"scalingMode",v.ScalingMode.None);h(this,"currentScale",1);h(this,"customCellSize",!1);if(!t)throw new Error("Render: L'\xE9l\xE9ment parent est requis");this.parentElement=t,this.fixedGridMode=!!(e.fixedCols&&e.fixedRows),this.fixedCols=e.fixedCols,this.fixedRows=e.fixedRows,this.cellAspectRatio=e.cellAspectRatio??1,this.cellWidth=e.cellWidth??8,this.cellHeight=e.cellHeight??8,this.fontSize=e.fontSize??12,this.fontFamily=e.fontFamily??"monospace",this.defaultFgColor=e.defaultFgColor??"#ffffff",this.defaultBgColor=e.defaultBgColor??"#000000",this.canvasBgColor=e.canvasBgColor!==void 0?e.canvasBgColor:null,this.showDebugGrid=e.showDebugGrid??!1,this.debugGridColor=e.debugGridColor??"rgba(144, 24, 24, 1)",this.scalingMode=e.scalingMode??v.ScalingMode.None,window.getComputedStyle(this.parentElement).position==="static"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminal2d-container",this.containerDiv.style.cssText=`
8
+ `,this.container.appendChild(this.canvas);let s=this.canvas.getContext("2d");if(!s)throw new Error("[GridOverlay] Impossible de cr\xE9er le contexte 2D");this.ctx=s,e&&(e.strokeColor&&(this.strokeColor=e.strokeColor),e.lineWidth!==void 0&&(this.lineWidth=e.lineWidth))}setDimensions(t,e,i,s,n=0,l=0){this.cols=t,this.rows=e,this.cellWidth=i,this.cellHeight=s,this.offsetX=n,this.offsetY=l}setCanvasSize(t,e){this.canvas.width=t,this.canvas.height=e,this.ctx.setTransform(1,0,0,1,0,0)}setStyle(t){t.strokeColor&&(this.strokeColor=t.strokeColor),t.lineWidth!==void 0&&(this.lineWidth=t.lineWidth)}setTransform(t,e,i,s,n){let l=s.left-n.left,r=s.top-n.top,a=s.width,o=s.height;(this.canvas.width!==a||this.canvas.height!==o)&&(this.canvas.width=a,this.canvas.height=o);let c=this.canvas.style;c.width=`${a}px`,c.height=`${o}px`,c.left=`${l}px`,c.top=`${r}px`}render(){if(!this.ctx)return;let t=this.cols*this.cellWidth,e=this.rows*this.cellHeight,i=t>0?this.canvas.width/t:1,s=e>0?this.canvas.height/e:1,n=Math.min(i,s),l=this.cellWidth*n,r=this.cellHeight*n,a=this.cols*l,o=this.rows*r,c=this.offsetX*n,g=this.offsetY*n;if(!(a===0||o===0)){this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.ctx.strokeStyle=this.strokeColor,this.ctx.lineWidth=Math.max(1,this.lineWidth*n),this.ctx.beginPath();for(let m=0;m<=this.cols;m++){let f=c+m*l+.5;this.ctx.moveTo(f,g),this.ctx.lineTo(f,g+o)}for(let m=0;m<=this.rows;m++){let f=g+m*r+.5;this.ctx.moveTo(c,f),this.ctx.lineTo(c+a,f)}this.ctx.stroke()}}update(t,e,i,s,n,l,r=0,a=0){this.setDimensions(t,e,i,s,r,a),this.setCanvasSize(n,l),this.render()}setVisible(t){this.canvas.style.display=t?"block":"none"}destroy(){this.canvas.parentElement&&this.canvas.parentElement.removeChild(this.canvas)}getCanvas(){return this.canvas}};u(R,"GridOverlay");var v=R;var p=require("@utsp/types");var E=class E{constructor(t,e={}){h(this,"containerDiv");h(this,"canvas");h(this,"ctx");h(this,"parentElement");h(this,"cells");h(this,"cols",0);h(this,"rows",0);h(this,"defaultFgColor");h(this,"defaultBgColor");h(this,"canvasBgColor");h(this,"cellWidth");h(this,"cellHeight");h(this,"offsetX",0);h(this,"offsetY",0);h(this,"imageAtlas");h(this,"showDebugGrid");h(this,"debugGridColor");h(this,"gridOverlay");h(this,"fixedGridMode");h(this,"fixedCols");h(this,"fixedRows");h(this,"cellAspectRatio");h(this,"resizeObserver");h(this,"paletteCache");h(this,"scalingMode",p.ScalingMode.None);h(this,"currentScale",1);h(this,"customCellSize",!1);if(!t)throw new Error("Render: L'\xE9l\xE9ment parent est requis");this.parentElement=t,this.fixedGridMode=!!(e.fixedCols&&e.fixedRows),this.fixedCols=e.fixedCols,this.fixedRows=e.fixedRows,this.cellAspectRatio=e.cellAspectRatio??1,this.cellWidth=e.cellWidth??8,this.cellHeight=e.cellHeight??8,this.defaultFgColor=e.defaultFgColor??"#ffffff",this.defaultBgColor=e.defaultBgColor??"#000000",this.canvasBgColor=e.canvasBgColor!==void 0?e.canvasBgColor:null,this.showDebugGrid=e.showDebugGrid??!1,this.debugGridColor=e.debugGridColor??"rgba(144, 24, 24, 1)",this.scalingMode=e.scalingMode??p.ScalingMode.None,window.getComputedStyle(this.parentElement).position==="static"&&(this.parentElement.style.position="relative"),this.containerDiv=document.createElement("div"),this.containerDiv.className="terminal2d-container",this.containerDiv.style.cssText=`
9
9
  position: absolute !important;
10
10
  top: 0 !important;
11
11
  left: 0 !important;
@@ -20,7 +20,7 @@
20
20
  align-items: center !important;
21
21
  isolation: isolate !important;
22
22
  pointer-events: none !important;
23
- `,this.canvas=document.createElement("canvas"),this.canvas.className="terminal2d-canvas",e.className&&(this.canvas.className+=" "+e.className),e.style&&Object.assign(this.canvas.style,e.style),this.canvas.style.imageRendering="pixelated",this.canvas.style.imageRendering="crisp-edges",this.containerDiv.appendChild(this.canvas),this.parentElement.appendChild(this.containerDiv);let s=this.canvas.getContext("2d",{alpha:!0,desynchronized:!1});if(!s)throw new Error("UTSPRender: Impossible d'obtenir le contexte 2D du canvas");this.ctx=s,this.ctx.imageSmoothingEnabled=!1,this.calculateGridSize(),this.cells=this.createEmptyGrid(),this.showDebugGrid&&(this.gridOverlay=new y(this.parentElement,{strokeColor:this.debugGridColor,lineWidth:1,zIndex:10})),this.enableAutoResize(),this.render()}calculateGridSize(){let t=this.parentElement.clientWidth||800,e=this.parentElement.clientHeight||600;if(!this.customCellSize){let o,c;if(this.fontType==="image"&&this.imageAtlas){let d=this.imageAtlas.getCellDimensions();o=d.width,c=d.height}else this.fontType==="bitmap"?(o=this.bitmapCharWidth,c=this.bitmapCharHeight):(o=Math.round(this.cellWidth)||10,c=Math.round(this.cellHeight)||14);this.cellWidth=Math.round(o),this.cellHeight=Math.round(c)}this.scalingMode===v.ScalingMode.Responsive?(this.cols=Math.floor(t/this.cellWidth)||1,this.rows=Math.floor(e/this.cellHeight)||1):this.fixedGridMode&&this.fixedCols&&this.fixedRows?(this.cols=this.fixedCols,this.rows=this.fixedRows):(this.cols=Math.floor(t/this.cellWidth)||1,this.rows=Math.floor(e/this.cellHeight)||1);let i=this.cols*this.cellWidth,s=this.rows*this.cellHeight,n=t/i,r=e/s,a=Math.min(n,r),l;switch(this.scalingMode){case v.ScalingMode.Integer:l=Math.max(1,Math.floor(a));break;case v.ScalingMode.Half:l=Math.max(.5,Math.floor(a*2)/2);break;case v.ScalingMode.Quarter:l=Math.max(.25,Math.floor(a*4)/4);break;case v.ScalingMode.Eighth:l=Math.max(.125,Math.floor(a*8)/8);break;case v.ScalingMode.Responsive:l=1;break;case v.ScalingMode.None:default:l=Math.max(.1,a);break}this.currentScale=l,this.canvas.width=i,this.canvas.height=s,this.ctx.imageSmoothingEnabled=!1,this.canvas.style.cssText=`
23
+ `,this.canvas=document.createElement("canvas"),this.canvas.className="terminal2d-canvas",e.className&&(this.canvas.className+=" "+e.className),e.style&&Object.assign(this.canvas.style,e.style),this.canvas.style.imageRendering="pixelated",this.canvas.style.imageRendering="crisp-edges",this.containerDiv.appendChild(this.canvas),this.parentElement.appendChild(this.containerDiv);let s=this.canvas.getContext("2d",{alpha:!0,desynchronized:!1});if(!s)throw new Error("UTSPRender: Impossible d'obtenir le contexte 2D du canvas");this.ctx=s,this.ctx.imageSmoothingEnabled=!1,this.calculateGridSize(),this.cells=this.createEmptyGrid(),this.showDebugGrid&&(this.gridOverlay=new v(this.parentElement,{strokeColor:this.debugGridColor,lineWidth:1,zIndex:10})),this.enableAutoResize(),this.render()}calculateGridSize(){let t=this.parentElement.clientWidth||800,e=this.parentElement.clientHeight||600;if(!this.customCellSize){let o,c;if(this.imageAtlas){let g=this.imageAtlas.getCellDimensions();o=g.width,c=g.height}else o=this.cellWidth,c=this.cellHeight;this.cellWidth=Math.round(o),this.cellHeight=Math.round(c)}this.scalingMode===p.ScalingMode.Responsive?(this.cols=Math.floor(t/this.cellWidth)||1,this.rows=Math.floor(e/this.cellHeight)||1):this.fixedGridMode&&this.fixedCols&&this.fixedRows?(this.cols=this.fixedCols,this.rows=this.fixedRows):(this.cols=Math.floor(t/this.cellWidth)||1,this.rows=Math.floor(e/this.cellHeight)||1);let i=this.cols*this.cellWidth,s=this.rows*this.cellHeight,n=t/i,l=e/s,r=Math.min(n,l),a;switch(this.scalingMode){case p.ScalingMode.Integer:a=Math.max(1,Math.floor(r));break;case p.ScalingMode.Half:a=Math.max(.5,Math.floor(r*2)/2);break;case p.ScalingMode.Quarter:a=Math.max(.25,Math.floor(r*4)/4);break;case p.ScalingMode.Eighth:a=Math.max(.125,Math.floor(r*8)/8);break;case p.ScalingMode.Responsive:a=1;break;case p.ScalingMode.None:default:a=Math.max(.1,r);break}this.currentScale=a,this.canvas.width=i,this.canvas.height=s,this.ctx.imageSmoothingEnabled=!1,this.canvas.style.cssText=`
24
24
  flex-shrink: 0 !important;
25
25
  flex-grow: 0 !important;
26
26
  width: ${i}px !important;
@@ -29,9 +29,9 @@
29
29
  image-rendering: crisp-edges !important;
30
30
  -ms-interpolation-mode: nearest-neighbor !important;
31
31
  transform-origin: center center !important;
32
- transform: scale(${l}) !important;
32
+ transform: scale(${a}) !important;
33
33
  will-change: transform !important;
34
34
  backface-visibility: hidden !important;
35
35
  pointer-events: auto !important;
36
36
  touch-action: none !important;
37
- `,this.fontType==="web"&&(this.fontSize=Math.round(this.cellHeight/14*12)),this.offsetX=0,this.offsetY=0}createEmptyGrid(){let t=[];for(let e=0;e<this.rows;e++){let i=[];for(let s=0;s<this.cols;s++)i.push({char:" ",fgColor:this.defaultFgColor,bgColor:this.defaultBgColor});t.push(i)}return t}enableAutoResize(){this.resizeObserver=new ResizeObserver(()=>{let t=this.cols,e=this.rows;if(this.calculateGridSize(),this.cols!==t||this.rows!==e){let i=this.cells;this.cells=this.createEmptyGrid();let s=Math.min(t,this.cols),n=Math.min(e,this.rows);for(let r=0;r<n;r++)for(let a=0;a<s;a++)this.cells[r][a]=i[r][a]}this.render()}),this.resizeObserver.observe(this.parentElement)}setCell(t,e,i,s,n){if(e<0||e>=this.rows||t<0||t>=this.cols)return;let r=i&&typeof i=="string"?i.charAt(0):" ";this.cells[e][t]={char:r,fgColor:s??this.defaultFgColor,bgColor:n??this.defaultBgColor}}getCell(t,e){return e<0||e>=this.rows||t<0||t>=this.cols?null:this.cells[e][t]}write(t,e,i,s,n){for(let r=0;r<i.length;r++)this.setCell(t+r,e,i[r],s,n)}fillRect(t,e,i,s,n=" ",r,a){for(let l=e;l<e+s;l++)for(let o=t;o<t+i;o++)this.setCell(o,l,n,r,a)}clear(){this.cells=this.createEmptyGrid()}setFromArray(t){let e=t.width*t.height;if(t.cells.length!==e)throw new Error(`Invalid array length: expected ${e} (${t.width}\xD7${t.height}), got ${t.cells.length}`);let i=0;for(let s=0;s<t.height;s++)for(let n=0;n<t.width;n++){let r=t.cells[i];s<this.rows&&n<this.cols&&this.setCell(n,s,r.char,r.fgColor,r.bgColor),i++}}render(t=!0){if(this.fontType==="bitmap"&&this.bitmapFont&&this.useImageDataRendering){this.renderWithImageData(t);return}this.renderClassic(t)}renderWithImageData(t=!0){if(!this.bitmapFont)return;let e=this.cols*this.bitmapCharWidth,i=this.rows*this.bitmapCharHeight;(!this.imageDataBuffer||this.imageDataBuffer.width!==e||this.imageDataBuffer.height!==i)&&(this.imageDataBuffer=this.ctx.createImageData(e,i));let s=this.imageDataBuffer.data;for(let o=0;o<this.rows;o++)for(let c=0;c<this.cols;c++){let d=this.cells[o][c],m=this.parseColorToRGB(d.bgColor),u=this.parseColorToRGB(d.fgColor),w=d.char.charCodeAt(0),b=this.bitmapFont.get(w);for(let C=0;C<this.bitmapCharHeight;C++)for(let p=0;p<this.bitmapCharWidth;p++){let S=c*this.bitmapCharWidth+p,x=((o*this.bitmapCharHeight+C)*e+S)*4,F=!1;if(b&&C<b.length){let U=b[C],$=1<<7-p;F=(U&$)!==0}F?(s[x]=u.r,s[x+1]=u.g,s[x+2]=u.b,s[x+3]=u.a):(s[x]=m.r,s[x+1]=m.g,s[x+2]=m.b,s[x+3]=m.a)}}t&&(this.canvasBgColor!==null?(this.ctx.fillStyle=this.canvasBgColor,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height)):this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)),this.ctx.imageSmoothingEnabled=!1,this.canvas.style.imageRendering="pixelated",this.canvas.style.imageRendering="crisp-edges";let n=document.createElement("canvas");n.width=e,n.height=i,n.getContext("2d").putImageData(this.imageDataBuffer,0,0);let a=this.cols*this.cellWidth,l=this.rows*this.cellHeight;this.ctx.drawImage(n,0,0,e,i,this.offsetX,this.offsetY,a,l),this.showDebugGrid&&this.drawDebugGrid()}parseColorToRGB(t){let e=/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/.exec(t);if(e)return{r:parseInt(e[1],10),g:parseInt(e[2],10),b:parseInt(e[3],10),a:e[4]?Math.round(parseFloat(e[4])*255):255};if(t.startsWith("#")){let n=/^#?([a-f\d])([a-f\d])([a-f\d])$/i;t=t.replace(n,(a,l,o,c)=>l+l+o+o+c+c);let r=/^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(t);if(r)return{r:parseInt(r[1],16),g:parseInt(r[2],16),b:parseInt(r[3],16),a:255}}let s={white:[255,255,255],black:[0,0,0],red:[255,0,0],green:[0,255,0],blue:[0,0,255],yellow:[255,255,0],cyan:[0,255,255],magenta:[255,0,255],transparent:[0,0,0]}[t.toLowerCase()];return s?{r:s[0],g:s[1],b:s[2],a:t==="transparent"?0:255}:{r:255,g:255,b:255,a:255}}renderClassic(t=!0){t&&(this.canvasBgColor!==null?(this.ctx.fillStyle=this.canvasBgColor,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height)):this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)),this.fontType==="bitmap"||this.fontType==="image"?(this.ctx.imageSmoothingEnabled=!1,this.canvas.style.imageRendering="pixelated",this.canvas.style.imageRendering="crisp-edges"):(this.ctx.imageSmoothingEnabled=!0,this.ctx.imageSmoothingQuality="high",this.canvas.style.imageRendering="auto",this.ctx.font=`${this.fontSize}px ${this.fontFamily}`,this.ctx.textBaseline="top",this.ctx.textRendering="optimizeLegibility");for(let e=0;e<this.rows;e++)for(let i=0;i<this.cols;i++){let s=this.cells[e][i],n=Math.floor(this.offsetX+i*this.cellWidth),r=Math.floor(this.offsetY+e*this.cellHeight),a=Math.floor(this.offsetX+(i+1)*this.cellWidth),l=Math.floor(this.offsetY+(e+1)*this.cellHeight),o=a-n,c=l-r;if((this.canvasBgColor!==null||s.bgColor!==this.defaultBgColor)&&(this.ctx.fillStyle=s.bgColor,this.ctx.fillRect(n,r,o,c)),s.char!==" ")if(this.fontType==="image"&&this.imageAtlas){let m=s.char.charCodeAt(0);this.imageAtlas.drawChar(this.ctx,m,n,r,o,c,s.fgColor)}else if(this.fontType==="bitmap"&&this.bitmapFont)this.drawBitmapChar(s.char,n,r,o,c,s.fgColor);else{this.ctx.fillStyle=s.fgColor;let m=n+(o-this.ctx.measureText(s.char).width)/2,u=r+(c-this.fontSize)/2;this.ctx.fillText(s.char,m,u)}}this.showDebugGrid&&this.drawDebugGrid()}drawBitmapChar(t,e,i,s,n,r){let a=t.charCodeAt(0);if(this.bitmapAtlas){this.bitmapAtlas.drawChar(this.ctx,a,e,i,s,n,r);return}if(!this.bitmapFont)return;let l=this.bitmapFont.get(a);if(!l)return;let o=s/this.bitmapCharWidth,c=n/this.bitmapCharHeight;this.ctx.fillStyle=r;for(let d=0;d<Math.min(l.length,this.bitmapCharHeight);d++){let m=l[d],u=i+d*c,w=i+(d+1)*c;for(let b=0;b<this.bitmapCharWidth;b++){let C=1<<7-b;if(m&C){let p=e+b*o,S=e+(b+1)*o;this.ctx.fillRect(p,u,S-p,w-u)}}}}drawDebugGrid(){if(!this.gridOverlay)return;let t=this.parentElement.clientWidth||800,e=this.parentElement.clientHeight||600;this.gridOverlay.update(this.cols,this.rows,this.cellWidth,this.cellHeight,t,e,this.offsetX,this.offsetY)}getCanvas(){return this.canvas}getContext(){return this.ctx}getDimensions(){return{cols:this.cols,rows:this.rows}}getCellDimensions(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getCellWidth(){return this.cellWidth}getCellHeight(){return this.cellHeight}getCurrentScale(){return this.currentScale}getScalingMode(){return this.scalingMode}getOffsets(){return{offsetX:this.offsetX,offsetY:this.offsetY}}setDebugGrid(t){this.showDebugGrid=t,t&&!this.gridOverlay?(this.gridOverlay=new y(this.parentElement,{strokeColor:this.debugGridColor,lineWidth:1,zIndex:10}),this.drawDebugGrid()):!t&&this.gridOverlay?(this.gridOverlay.destroy(),this.gridOverlay=void 0):t&&this.gridOverlay&&this.gridOverlay.setVisible(!0)}setCanvasBackgroundColor(t){this.canvasBgColor=t}getCanvasBackgroundColor(){return this.canvasBgColor}setFixedGrid(t,e,i){this.fixedGridMode=!0,this.fixedCols=t,this.fixedRows=e,i!==void 0&&(this.cellAspectRatio=i);let s=this.cols,n=this.rows,r=this.cells;if(this.calculateGridSize(),this.cols!==s||this.rows!==n){this.cells=this.createEmptyGrid();let a=Math.min(s,this.cols),l=Math.min(n,this.rows);for(let o=0;o<l;o++)for(let c=0;c<a;c++)this.cells[o][c]=r[o][c]}this.render()}setAdaptiveGrid(t,e){this.fixedGridMode=!1,this.fixedCols=void 0,this.fixedRows=void 0,t!==void 0&&(this.cellWidth=t),e!==void 0&&(this.cellHeight=e);let i=this.cols,s=this.rows,n=this.cells;if(this.calculateGridSize(),this.cols!==i||this.rows!==s){this.cells=this.createEmptyGrid();let r=Math.min(i,this.cols),a=Math.min(s,this.rows);for(let l=0;l<a;l++)for(let o=0;o<r;o++)this.cells[l][o]=n[l][o]}this.render()}isFixedGridMode(){return this.fixedGridMode}setDebugGridColor(t){this.debugGridColor=t}isDebugGridEnabled(){return this.showDebugGrid}setImageDataRendering(t){this.useImageDataRendering=t,t&&this.fontType==="bitmap"?console.warn("[Render] ImageData rendering enabled (optimized for benchmarks)"):t&&(console.warn("[Render] ImageData rendering requires bitmap font, keeping classic mode"),this.useImageDataRendering=!1)}isImageDataRenderingEnabled(){return this.useImageDataRendering}setWebFont(t,e){this.fontType="web",this.fontFamily=t,e!==void 0&&(this.fontSize=e),this.bitmapFont=void 0,this.bitmapAtlas=void 0,this.useImageDataRendering=!1,this.calculateGridSize(),this.cells=this.createEmptyGrid()}setBitmapFont(t,e,i,s,n){this.fontType="bitmap",this.bitmapFont=t,this.bitmapCharWidth=e,this.bitmapCharHeight=i,this.bitmapAtlas=new M(t,e,i,s,n),this.cellWidth=s,this.cellHeight=n,this.calculateGridSize(),this.cells=this.createEmptyGrid()}async setImageFont(t,e,i,s,n,r){this.fontType="image",this.imageAtlas=new H({glyphWidth:e,glyphHeight:i,cellWidth:s,cellHeight:n,atlasBlocks:r}),await this.imageAtlas.loadFromPNG(t),this.cellWidth=s,this.cellHeight=n,this.bitmapCharWidth=e,this.bitmapCharHeight=i,this.calculateGridSize(),this.cells=this.createEmptyGrid()}getFontType(){return this.fontType}getBitmapFont(){return this.bitmapFont}getBitmapCharDimensions(){return this.fontType!=="bitmap"?null:{width:this.bitmapCharWidth,height:this.bitmapCharHeight}}setPalette(t){this.paletteCache=t}convertColor(t,e){if(t==null||isNaN(t))return this.defaultFgColor;if(t===255)return"rgba(0, 0, 0, 0)";if(t<0||t>=e.length)return this.defaultFgColor;let i=e[t];return!i||typeof i.r!="number"?this.defaultFgColor:`rgba(${i.r}, ${i.g}, ${i.b}, ${i.a/255})`}renderDirect(t,e,i,s,n){for(let r=0;r<e&&r<this.rows;r++)for(let a=0;a<t&&a<this.cols;a++){let l=r*t+a;if(l>=i.length)break;let o=i[l];if(!o)continue;let c=this.convertColor(o.fgColorIndex,s),d=this.convertColor(o.bgColorIndex,s);this.setCell(a,r,o.char??" ",c,d)}this.render(n)}renderDisplayData(t){if(!t||!t.cells||t.cells.length===0){console.warn("[Terminal2D] Empty display data");return}if(t.width===0||t.height===0){console.warn("[Terminal2D] Invalid display dimensions:",t.width,t.height);return}(t.width!==this.cols||t.height!==this.rows)&&this.setFixedGrid(t.width,t.height,this.cellAspectRatio);let e=this.paletteCache??t.palette;if(!e||e.length===0){console.error("[Terminal2D] No palette available (neither cached nor in display)");return}if(t.passes&&t.passes.length>0)for(let i=0;i<t.passes.length;i++){let s=t.passes[i];this.renderDirect(t.width,t.height,s.cells,e,i===0)}else this.renderDirect(t.width,t.height,t.cells,e,!0)}isReady(){return!0}getCols(){return this.cols}getRows(){return this.rows}resize(t,e){this.setFixedGrid(t,e)}setScalingMode(t){if(this.scalingMode===t)return;let e=this.cols,i=this.rows;if(this.scalingMode=t,this.calculateGridSize(),this.cols!==e||this.rows!==i){let s=this.cells;if(this.cells=this.createEmptyGrid(),s&&s.length>0){let n=Math.min(e,this.cols),r=Math.min(i,this.rows);for(let a=0;a<r;a++)for(let l=0;l<n;l++)s[a]&&s[a][l]&&(this.cells[a][l]=s[a][l])}}this.render()}setCellSize(t,e){let i=Math.max(1,Math.min(255,Math.round(t))),s=Math.max(1,Math.min(255,Math.round(e)));if(this.cellWidth===i&&this.cellHeight===s)return;let n=this.cols,r=this.rows;if(this.cellWidth=i,this.cellHeight=s,this.customCellSize=!0,this.calculateGridSize(),this.cols!==n||this.rows!==r){let a=this.cells;if(this.cells=this.createEmptyGrid(),a&&a.length>0){let l=Math.min(n,this.cols),o=Math.min(r,this.rows);for(let c=0;c<o;c++)for(let d=0;d<l;d++)a[c]&&a[c][d]&&(this.cells[c][d]=a[c][d])}}this.render()}getCellSize(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getAvailableSize(){return{width:this.parentElement.clientWidth,height:this.parentElement.clientHeight}}getMaxCells(){return 65536}destroy(){this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=void 0),this.gridOverlay&&(this.gridOverlay.destroy(),this.gridOverlay=void 0),this.containerDiv.parentElement&&this.containerDiv.parentElement.removeChild(this.containerDiv)}};f(k,"Terminal2D");var A=k;var I=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff","#080808","#121212","#1c1c1c","#262626","#303030","#3a3a3a","#444444","#4e4e4e","#585858","#626262","#6c6c6c","#767676","#808080","#8a8a8a","#949494","#9e9e9e","#a80000","#00a800","#a8a800","#0000a8","#a800a8","#00a8a8","#a8a8a8","#545454","#fc5454","#54fc54","#fcfc54","#5454fc","#fc54fc","#54fcfc","#fcfcfc","#000000",...Array(192).fill("#808080")];function z(g,t=I){return g<0||g>=t.length?"#ff00ff":t[g]}f(z,"paletteIndexToColor");function L(g,t=I){let e=t.indexOf(g.toLowerCase());return e>=0?e:0}f(L,"colorToPaletteIndex");var O=require("@utsp/types");
37
+ `,this.offsetX=0,this.offsetY=0}createEmptyGrid(){let t=[];for(let e=0;e<this.rows;e++){let i=[];for(let s=0;s<this.cols;s++)i.push({char:" ",fgColor:this.defaultFgColor,bgColor:this.defaultBgColor});t.push(i)}return t}enableAutoResize(){this.resizeObserver=new ResizeObserver(()=>{let t=this.cols,e=this.rows;if(this.calculateGridSize(),this.cols!==t||this.rows!==e){let i=this.cells;this.cells=this.createEmptyGrid();let s=Math.min(t,this.cols),n=Math.min(e,this.rows);for(let l=0;l<n;l++)for(let r=0;r<s;r++)this.cells[l][r]=i[l][r]}this.render()}),this.resizeObserver.observe(this.parentElement)}setCell(t,e,i,s,n){if(e<0||e>=this.rows||t<0||t>=this.cols)return;let l=i&&typeof i=="string"?i.charAt(0):" ";this.cells[e][t]={char:l,fgColor:s??this.defaultFgColor,bgColor:n??this.defaultBgColor}}getCell(t,e){return e<0||e>=this.rows||t<0||t>=this.cols?null:this.cells[e][t]}write(t,e,i,s,n){for(let l=0;l<i.length;l++)this.setCell(t+l,e,i[l],s,n)}fillRect(t,e,i,s,n=" ",l,r){for(let a=e;a<e+s;a++)for(let o=t;o<t+i;o++)this.setCell(o,a,n,l,r)}clear(){this.cells=this.createEmptyGrid()}setFromArray(t){let e=t.width*t.height;if(t.cells.length!==e)throw new Error(`Invalid array length: expected ${e} (${t.width}\xD7${t.height}), got ${t.cells.length}`);let i=0;for(let s=0;s<t.height;s++)for(let n=0;n<t.width;n++){let l=t.cells[i];s<this.rows&&n<this.cols&&this.setCell(n,s,l.char,l.fgColor,l.bgColor),i++}}render(t=!0){this.renderClassic(t)}renderClassic(t=!0){t&&(this.canvasBgColor!==null?(this.ctx.fillStyle=this.canvasBgColor,this.ctx.fillRect(0,0,this.canvas.width,this.canvas.height)):this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height)),this.ctx.imageSmoothingEnabled=!1,this.canvas.style.imageRendering="pixelated",this.canvas.style.imageRendering="crisp-edges";for(let e=0;e<this.rows;e++)for(let i=0;i<this.cols;i++){let s=this.cells[e][i],n=Math.floor(this.offsetX+i*this.cellWidth),l=Math.floor(this.offsetY+e*this.cellHeight),r=Math.floor(this.offsetX+(i+1)*this.cellWidth),a=Math.floor(this.offsetY+(e+1)*this.cellHeight),o=r-n,c=a-l;if((this.canvasBgColor!==null||s.bgColor!==this.defaultBgColor)&&(this.ctx.fillStyle=s.bgColor,this.ctx.fillRect(n,l,o,c)),s.char!==" "&&this.imageAtlas){let m=s.char.charCodeAt(0);this.imageAtlas.drawChar(this.ctx,m,n,l,o,c,s.fgColor)}}this.showDebugGrid&&this.drawDebugGrid()}drawDebugGrid(){if(!this.gridOverlay)return;let t=this.parentElement.clientWidth||800,e=this.parentElement.clientHeight||600;this.gridOverlay.update(this.cols,this.rows,this.cellWidth,this.cellHeight,t,e,this.offsetX,this.offsetY)}getCanvas(){return this.canvas}getContext(){return this.ctx}getDimensions(){return{cols:this.cols,rows:this.rows}}getCellDimensions(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getCellWidth(){return this.cellWidth}getCellHeight(){return this.cellHeight}getCurrentScale(){return this.currentScale}getScalingMode(){return this.scalingMode}getOffsets(){return{offsetX:this.offsetX,offsetY:this.offsetY}}setDebugGrid(t){this.showDebugGrid=t,t&&!this.gridOverlay?(this.gridOverlay=new v(this.parentElement,{strokeColor:this.debugGridColor,lineWidth:1,zIndex:10}),this.drawDebugGrid()):!t&&this.gridOverlay?(this.gridOverlay.destroy(),this.gridOverlay=void 0):t&&this.gridOverlay&&this.gridOverlay.setVisible(!0)}setCanvasBackgroundColor(t){this.canvasBgColor=t}getCanvasBackgroundColor(){return this.canvasBgColor}setFixedGrid(t,e,i){this.fixedGridMode=!0,this.fixedCols=t,this.fixedRows=e,i!==void 0&&(this.cellAspectRatio=i);let s=this.cols,n=this.rows,l=this.cells;if(this.calculateGridSize(),this.cols!==s||this.rows!==n){this.cells=this.createEmptyGrid();let r=Math.min(s,this.cols),a=Math.min(n,this.rows);for(let o=0;o<a;o++)for(let c=0;c<r;c++)this.cells[o][c]=l[o][c]}this.render()}setAdaptiveGrid(t,e){this.fixedGridMode=!1,this.fixedCols=void 0,this.fixedRows=void 0,t!==void 0&&(this.cellWidth=t),e!==void 0&&(this.cellHeight=e);let i=this.cols,s=this.rows,n=this.cells;if(this.calculateGridSize(),this.cols!==i||this.rows!==s){this.cells=this.createEmptyGrid();let l=Math.min(i,this.cols),r=Math.min(s,this.rows);for(let a=0;a<r;a++)for(let o=0;o<l;o++)this.cells[a][o]=n[a][o]}this.render()}isFixedGridMode(){return this.fixedGridMode}setDebugGridColor(t){this.debugGridColor=t}isDebugGridEnabled(){return this.showDebugGrid}async setImageFont(t,e,i,s,n,l){this.imageAtlas=new C({glyphWidth:e,glyphHeight:i,cellWidth:s,cellHeight:n,atlasBlocks:l}),await this.imageAtlas.loadFromPNG(t),this.cellWidth=s,this.cellHeight=n,this.calculateGridSize(),this.fixedGridMode||(this.calculateGridSize(),this.cells=this.createEmptyGrid()),this.render()}async setImageFontStructure(t,e,i,s,n){let l=this.imageAtlas;if(this.imageAtlas=new C({glyphWidth:t,glyphHeight:e,cellWidth:i,cellHeight:s,atlasBlocks:n}),this.imageAtlas.prepare(),l){let r=l.getCanvas();if(r&&l.getGlyphWidth()===t&&l.getGlyphHeight()===e){let o=this.imageAtlas.getCanvas()?.getContext("2d");if(o){let c=16*t,g=16*e;r.width>=c&&r.height>=g&&o.drawImage(r,0,0,c,g,0,0,c,g)}}}this.cellWidth=i,this.cellHeight=s,this.fixedGridMode||(this.calculateGridSize(),this.cells=this.createEmptyGrid())}async setImageFontBlock(t,e){if(!this.imageAtlas){console.warn("[Terminal2D] Cannot load block: no atlas initialized");return}await this.imageAtlas.loadBlock(t,e),this.render()}setPalette(t){this.paletteCache=t}convertColor(t,e){if(t==null||isNaN(t))return this.defaultFgColor;if(t===255)return"rgba(0, 0, 0, 0)";if(t<0||t>=e.length)return this.defaultFgColor;let i=e[t];return!i||typeof i.r!="number"?this.defaultFgColor:`rgba(${i.r}, ${i.g}, ${i.b}, ${i.a/255})`}renderDirect(t,e,i,s,n){for(let l=0;l<e&&l<this.rows;l++)for(let r=0;r<t&&r<this.cols;r++){let a=l*t+r;if(a>=i.length)break;let o=i[a];if(!o)continue;let c=this.convertColor(o.fgColorIndex,s),g=this.convertColor(o.bgColorIndex,s);this.setCell(r,l,o.char??" ",c,g)}this.render(n)}renderDisplayData(t){if(!t||!t.cells||t.cells.length===0){console.warn("[Terminal2D] Empty display data");return}if(t.width===0||t.height===0){console.warn("[Terminal2D] Invalid display dimensions:",t.width,t.height);return}(t.width!==this.cols||t.height!==this.rows)&&this.setFixedGrid(t.width,t.height,this.cellAspectRatio);let e=this.paletteCache??t.palette;if(!e||e.length===0){console.error("[Terminal2D] No palette available (neither cached nor in display)");return}if(t.passes&&t.passes.length>0)for(let i=0;i<t.passes.length;i++){let s=t.passes[i];this.renderDirect(t.width,t.height,s.cells,e,i===0)}else this.renderDirect(t.width,t.height,t.cells,e,!0)}isReady(){return!0}getCols(){return this.cols}getRows(){return this.rows}resize(t,e){this.setFixedGrid(t,e)}setScalingMode(t){if(this.scalingMode===t)return;let e=this.cols,i=this.rows;if(this.scalingMode=t,this.calculateGridSize(),this.cols!==e||this.rows!==i){let s=this.cells;if(this.cells=this.createEmptyGrid(),s&&s.length>0){let n=Math.min(e,this.cols),l=Math.min(i,this.rows);for(let r=0;r<l;r++)for(let a=0;a<n;a++)s[r]&&s[r][a]&&(this.cells[r][a]=s[r][a])}}this.render()}setCellSize(t,e){let i=Math.max(1,Math.min(255,Math.round(t))),s=Math.max(1,Math.min(255,Math.round(e)));if(this.cellWidth===i&&this.cellHeight===s)return;let n=this.cols,l=this.rows;if(this.cellWidth=i,this.cellHeight=s,this.customCellSize=!0,this.calculateGridSize(),this.cols!==n||this.rows!==l){let r=this.cells;if(this.cells=this.createEmptyGrid(),r&&r.length>0){let a=Math.min(n,this.cols),o=Math.min(l,this.rows);for(let c=0;c<o;c++)for(let g=0;g<a;g++)r[c]&&r[c][g]&&(this.cells[c][g]=r[c][g])}}this.render()}getCellSize(){return{cellWidth:this.cellWidth,cellHeight:this.cellHeight}}getAvailableSize(){return{width:this.parentElement.clientWidth,height:this.parentElement.clientHeight}}getMaxCells(){return 65536}destroy(){this.resizeObserver&&(this.resizeObserver.disconnect(),this.resizeObserver=void 0),this.gridOverlay&&(this.gridOverlay.destroy(),this.gridOverlay=void 0),this.containerDiv.parentElement&&this.containerDiv.parentElement.removeChild(this.containerDiv)}};u(E,"Terminal2D");var M=E;var H=["#000000","#800000","#008000","#808000","#000080","#800080","#008080","#c0c0c0","#808080","#ff0000","#00ff00","#ffff00","#0000ff","#ff00ff","#00ffff","#ffffff","#080808","#121212","#1c1c1c","#262626","#303030","#3a3a3a","#444444","#4e4e4e","#585858","#626262","#6c6c6c","#767676","#808080","#8a8a8a","#949494","#9e9e9e","#a80000","#00a800","#a8a800","#0000a8","#a800a8","#00a8a8","#a8a8a8","#545454","#fc5454","#54fc54","#fcfc54","#5454fc","#fc54fc","#54fcfc","#fcfcfc","#000000",...Array(192).fill("#808080")];function G(d,t=H){return d<0||d>=t.length?"#ff00ff":t[d]}u(G,"paletteIndexToColor");function A(d,t=H){let e=t.indexOf(d.toLowerCase());return e>=0?e:0}u(A,"colorToPaletteIndex");var k=require("@utsp/types");
@@ -51,6 +51,7 @@ declare function getCharGridPosition(charCode: number, blocks: AtlasBlocks): {
51
51
  row: number;
52
52
  };
53
53
 
54
+ type BitmapFont = Map<number, Uint8Array>;
54
55
  /**
55
56
  * Représente une cellule du terminal
56
57
  */
@@ -80,25 +81,6 @@ interface TerminalData {
80
81
  bgColor: string;
81
82
  }>;
82
83
  }
83
- /**
84
- * Police bitmap matricielle
85
- * Map qui associe un code de caractère (charCode) à une représentation bitmap 8x8
86
- * Chaque Uint8Array contient 8 octets, un par ligne de pixels
87
- */
88
- type BitmapFont$1 = Map<number, Uint8Array>;
89
- /**
90
- * Type de police à utiliser
91
- */
92
- type FontType = {
93
- type: 'web';
94
- fontFamily: string;
95
- fontSize: number;
96
- } | {
97
- type: 'bitmap';
98
- font: BitmapFont$1;
99
- charWidth: number;
100
- charHeight: number;
101
- };
102
84
  /**
103
85
  * Options pour la configuration du terminal
104
86
  */
@@ -107,10 +89,6 @@ interface RenderOptions {
107
89
  cellWidth?: number;
108
90
  /** Hauteur d'une cellule en pixels (défaut: 8) - ignoré en mode fixedGrid */
109
91
  cellHeight?: number;
110
- /** Taille de la police en pixels (défaut: 12) */
111
- fontSize?: number;
112
- /** Famille de police (défaut: "monospace") */
113
- fontFamily?: string;
114
92
  /** Couleur de texte par défaut (défaut: "#ffffff") */
115
93
  defaultFgColor?: string;
116
94
  /** Couleur de fond par défaut (défaut: "#000000") */
@@ -159,8 +137,6 @@ declare class Terminal2D implements IRenderer {
159
137
  private cells;
160
138
  private cols;
161
139
  private rows;
162
- private fontSize;
163
- private fontFamily;
164
140
  private defaultFgColor;
165
141
  private defaultBgColor;
166
142
  private canvasBgColor;
@@ -168,12 +144,7 @@ declare class Terminal2D implements IRenderer {
168
144
  private cellHeight;
169
145
  private offsetX;
170
146
  private offsetY;
171
- private fontType;
172
- private bitmapFont?;
173
- private bitmapAtlas?;
174
147
  private imageAtlas?;
175
- private bitmapCharWidth;
176
- private bitmapCharHeight;
177
148
  private showDebugGrid;
178
149
  private debugGridColor;
179
150
  private gridOverlay?;
@@ -182,8 +153,6 @@ declare class Terminal2D implements IRenderer {
182
153
  private fixedRows?;
183
154
  private cellAspectRatio;
184
155
  private resizeObserver?;
185
- private imageDataBuffer?;
186
- private useImageDataRendering;
187
156
  private paletteCache?;
188
157
  private scalingMode;
189
158
  private currentScale;
@@ -283,25 +252,10 @@ declare class Terminal2D implements IRenderer {
283
252
  */
284
253
  render(clearCanvas?: boolean): void;
285
254
  /**
286
- * Rendu ultra-rapide avec ImageData (bitmap)
287
- * ~10-20× plus rapide que fillRect en boucle
288
- * Fonctionne avec scaling : buffer natif 8×8 puis drawImage() pour upscale
289
- * @param clearCanvas - Whether to clear the canvas before rendering
290
- */
291
- private renderWithImageData;
292
- /**
293
- * Parse une couleur CSS en composantes RGBA
294
- */
295
- private parseColorToRGB;
296
- /**
297
- * Rendu classique avec fillRect/fillText (compatible scaling, web fonts, etc.)
255
+ * Rendu classique avec fillRect + atlas/bitmap
298
256
  * @param clearCanvas - Whether to clear the canvas before rendering
299
257
  */
300
258
  private renderClassic;
301
- /**
302
- * Dessine un caractère en utilisant une police bitmap
303
- */
304
- private drawBitmapChar;
305
259
  /**
306
260
  * Dessine une grille de débogage pour visualiser les cellules
307
261
  */
@@ -394,33 +348,6 @@ declare class Terminal2D implements IRenderer {
394
348
  * Vérifie si la grille de débogage est activée
395
349
  */
396
350
  isDebugGridEnabled(): boolean;
397
- /**
398
- * Active ou désactive le rendu optimisé avec ImageData
399
- * Uniquement disponible pour les polices bitmap à taille native (pas de scaling)
400
- * Environ 10-20× plus rapide que le rendu classique, idéal pour les benchmarks
401
- *
402
- * @param enable - true pour activer, false pour désactiver
403
- */
404
- setImageDataRendering(enable: boolean): void;
405
- /**
406
- * Vérifie si le rendu ImageData est activé
407
- */
408
- isImageDataRenderingEnabled(): boolean;
409
- /**
410
- * Configure une police web (CSS)
411
- * @param fontFamily - Nom de la police CSS (ex: "Courier New", "monospace")
412
- * @param fontSize - Taille de la police en pixels (optionnel, garde la taille actuelle si non spécifié)
413
- */
414
- setWebFont(fontFamily: string, fontSize?: number): void;
415
- /**
416
- * Configure une police bitmap matricielle
417
- * @param font - Map contenant les définitions bitmap des caractères (charCode -> Uint8Array)
418
- * @param charWidth - Largeur du glyphe en pixels (bitmap source)
419
- * @param charHeight - Hauteur du glyphe en pixels (bitmap source)
420
- * @param cellWidth - Largeur de la cellule de rendu en pixels
421
- * @param cellHeight - Hauteur de la cellule de rendu en pixels
422
- */
423
- setBitmapFont(font: BitmapFont$1, charWidth: number, charHeight: number, cellWidth: number, cellHeight: number): void;
424
351
  /**
425
352
  * Configure une police image (atlas PNG)
426
353
  * @param imageData - Données PNG brutes
@@ -432,20 +359,13 @@ declare class Terminal2D implements IRenderer {
432
359
  */
433
360
  setImageFont(imageData: Uint8Array, glyphWidth: number, glyphHeight: number, cellWidth: number, cellHeight: number, atlasBlocks: AtlasBlocks): Promise<void>;
434
361
  /**
435
- * Retourne le type de police actuellement utilisé
362
+ * Initialise la structure pour une police progressive
436
363
  */
437
- getFontType(): 'web' | 'bitmap' | 'image';
364
+ setImageFontStructure(glyphWidth: number, glyphHeight: number, cellWidth: number, cellHeight: number, atlasBlocks: AtlasBlocks): Promise<void>;
438
365
  /**
439
- * Retourne la police bitmap actuelle (si applicable)
366
+ * Ajoute un bloc d'image à la police courante
440
367
  */
441
- getBitmapFont(): BitmapFont$1 | undefined;
442
- /**
443
- * Retourne les dimensions de caractère bitmap (si applicable)
444
- */
445
- getBitmapCharDimensions(): {
446
- width: number;
447
- height: number;
448
- } | null;
368
+ setImageFontBlock(blockIndex: number, data: Uint8Array): Promise<void>;
449
369
  /**
450
370
  * Set color palette (IRenderer contract).
451
371
  * Called by ClientRuntime when Core palette changes.
@@ -545,143 +465,6 @@ declare class Terminal2D implements IRenderer {
545
465
  destroy(): void;
546
466
  }
547
467
 
548
- /**
549
- * Police bitmap matricielle
550
- * Map qui associe un code de caractère (charCode) à une représentation bitmap
551
- */
552
- type BitmapFont = Map<number, Uint8Array>;
553
- /**
554
- * Atlas à une résolution spécifique
555
- */
556
- interface AtlasResolution {
557
- canvas: HTMLCanvasElement;
558
- ctx: CanvasRenderingContext2D;
559
- scale: number;
560
- charWidth: number;
561
- charHeight: number;
562
- }
563
- /**
564
- * Classe pour générer et gérer un atlas de police bitmap multi-résolution
565
- * Convertit une police matricielle (bits) en plusieurs textures canvas à différentes échelles
566
- * pour un rendu ultra-rapide avec qualité optimale quelque soit le zoom
567
- *
568
- * Utilise un cache LRU de glyphes colorés pour éviter la re-colorisation
569
- */
570
- declare class BitmapFontAtlas {
571
- private atlases;
572
- private charMap;
573
- private baseCharWidth;
574
- private baseCharHeight;
575
- private baseCellWidth;
576
- private baseCellHeight;
577
- private atlasColumns;
578
- private font;
579
- private readonly SCALES;
580
- private colorCache;
581
- private readonly MAX_CACHE_SIZE;
582
- /**
583
- * Construit un atlas de police bitmap multi-résolution
584
- * @param font La police bitmap source
585
- * @param charWidth Largeur de base d'un caractère en pixels (taille du glyphe dans l'atlas)
586
- * @param charHeight Hauteur de base d'un caractère en pixels (taille du glyphe dans l'atlas)
587
- * @param cellWidth Largeur de base d'une cellule en pixels (peut être > charWidth pour l'espacement)
588
- * @param cellHeight Hauteur de base d'une cellule en pixels (peut être > charHeight pour l'espacement)
589
- */
590
- constructor(font: BitmapFont, charWidth: number, charHeight: number, cellWidth?: number, cellHeight?: number); /**
591
- * Génère les 4 atlas à différentes résolutions (1x, 2x, 4x, 8x)
592
- * Très rapide: ~4-8ms pour 256 caractères × 4 résolutions
593
- */
594
- private generateAtlases;
595
- /**
596
- * Récupère ou crée un atlas pour une échelle donnée
597
- */
598
- private getOrCreateAtlas;
599
- /**
600
- * Rend un caractère bitmap dans un atlas à une résolution donnée
601
- * Utilise fillRect pour un rendu ultra-rapide
602
- */
603
- private renderBitmapToAtlas;
604
- /**
605
- * Dessine un caractère en utilisant le cache de glyphes colorés
606
- * Ultra-rapide: 1 seul drawImage() par caractère
607
- * Utilise ImageData pour coloriser + Canvas cache pour éviter la re-colorisation
608
- *
609
- * @param ctx - Contexte de destination
610
- * @param charCode - Code du caractère à dessiner
611
- * @param x - Position X de destination (coin de la cellule)
612
- * @param y - Position Y de destination (coin de la cellule)
613
- * @param width - Largeur de la cellule de destination
614
- * @param height - Hauteur de la cellule de destination
615
- * @param color - Couleur du caractère (format CSS)
616
- */
617
- drawChar(ctx: CanvasRenderingContext2D, charCode: number, x: number, y: number, width: number, height: number, color: string): void;
618
- /**
619
- * Crée un glyphe colorisé à partir de l'atlas blanc
620
- * Utilise ImageData pour une colorisation ultra-rapide
621
- */
622
- private createColoredGlyph;
623
- /**
624
- * Convertit une couleur hex en RGB
625
- */
626
- private hexToRgb;
627
- /**
628
- * Élimine les entrées les moins récemment utilisées du cache (LRU)
629
- */
630
- private evictLRU;
631
- /**
632
- * Retourne le canvas d'atlas pour une résolution donnée (pour débogage/visualisation)
633
- * Par défaut retourne l'atlas 1x
634
- */
635
- getAtlasCanvas(scale?: number): HTMLCanvasElement | undefined;
636
- /**
637
- * Retourne tous les atlas disponibles
638
- */
639
- getAllAtlases(): Map<number, AtlasResolution>;
640
- /**
641
- * Retourne les dimensions de base d'un caractère
642
- */
643
- getCharDimensions(): {
644
- width: number;
645
- height: number;
646
- };
647
- /**
648
- * Retourne le nombre de caractères dans l'atlas
649
- */
650
- getCharCount(): number;
651
- /**
652
- * Vérifie si un caractère existe dans l'atlas
653
- */
654
- hasChar(charCode: number): boolean;
655
- /**
656
- * Retourne les dimensions d'un atlas à une résolution donnée
657
- */
658
- getAtlasDimensions(scale?: number): {
659
- width: number;
660
- height: number;
661
- } | undefined;
662
- /**
663
- * Exporte un atlas en Data URL (pour débogage)
664
- * Permet de visualiser l'atlas ou de le sauvegarder
665
- */
666
- toDataURL(scale?: number, type?: string): string | undefined;
667
- /**
668
- * Retourne les statistiques du cache de glyphes colorés
669
- */
670
- getCacheStats(): {
671
- size: number;
672
- maxSize: number;
673
- hitRate?: number;
674
- };
675
- /**
676
- * Vide le cache de glyphes colorés
677
- */
678
- clearCache(): void;
679
- /**
680
- * Libère les ressources
681
- */
682
- destroy(): void;
683
- }
684
-
685
468
  /**
686
469
  * ImageFontAtlas - Atlas for PNG-based fonts with multi-block support
687
470
  *
@@ -721,7 +504,29 @@ declare class ImageFontAtlas {
721
504
  private readonly MAX_CACHE_SIZE;
722
505
  constructor(config: ImageFontAtlasConfig);
723
506
  /**
724
- * Load atlas from PNG binary data
507
+ * Get the underlying canvas method
508
+ */
509
+ getCanvas(): HTMLCanvasElement | null;
510
+ /**
511
+ * Get glyph width
512
+ */
513
+ getGlyphWidth(): number;
514
+ /**
515
+ * Get glyph height
516
+ */
517
+ getGlyphHeight(): number;
518
+ /**
519
+ * Initialize empty atlas properties
520
+ */
521
+ prepare(): void;
522
+ /**
523
+ * Load a block into the atlas
524
+ * @param blockIndex Block index (0-15)
525
+ * @param pngData PNG data for the block
526
+ */
527
+ loadBlock(blockIndex: number, pngData: Uint8Array): Promise<void>;
528
+ /**
529
+ * Load atlas from PNG binary data (Legacy Monolithic)
725
530
  * @param pngData PNG image as Uint8Array
726
531
  * @returns Promise that resolves when atlas is loaded
727
532
  */
@@ -965,5 +770,5 @@ declare function paletteIndexToColor(index: number, palette?: readonly string[])
965
770
  */
966
771
  declare function colorToPaletteIndex(color: string, palette?: readonly string[]): number;
967
772
 
968
- export { BitmapFontAtlas, DEFAULT_PALETTE, GridOverlay, ImageFontAtlas, Terminal2D, colorToPaletteIndex, getAtlasColumns, getCharGridPosition, getMaxCharCode, paletteIndexToColor };
969
- export type { AtlasBlocks, BitmapFont$1 as BitmapFont, FontType, ImageFontAtlasConfig, RenderOptions, TerminalCell, TerminalData };
773
+ export { DEFAULT_PALETTE, GridOverlay, ImageFontAtlas, Terminal2D, colorToPaletteIndex, getAtlasColumns, getCharGridPosition, getMaxCharCode, paletteIndexToColor };
774
+ export type { AtlasBlocks, BitmapFont, ImageFontAtlasConfig, RenderOptions, TerminalCell, TerminalData };