@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 +5 -5
- package/dist/2d/index.d.ts +31 -226
- package/dist/2d/index.mjs +5 -5
- package/dist/gl/index.cjs +7 -7
- package/dist/gl/index.d.ts +21 -50
- package/dist/gl/index.mjs +7 -7
- package/dist/index.cjs +10 -10
- package/dist/index.d.ts +799 -1017
- package/dist/index.mjs +10 -10
- package/package.json +2 -2
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,
|
|
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
|
|
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(${
|
|
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");
|
package/dist/2d/index.d.ts
CHANGED
|
@@ -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
|
|
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
|
-
*
|
|
362
|
+
* Initialise la structure pour une police progressive
|
|
436
363
|
*/
|
|
437
|
-
|
|
364
|
+
setImageFontStructure(glyphWidth: number, glyphHeight: number, cellWidth: number, cellHeight: number, atlasBlocks: AtlasBlocks): Promise<void>;
|
|
438
365
|
/**
|
|
439
|
-
*
|
|
366
|
+
* Ajoute un bloc d'image à la police courante
|
|
440
367
|
*/
|
|
441
|
-
|
|
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
|
-
*
|
|
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 {
|
|
969
|
-
export type { AtlasBlocks, BitmapFont
|
|
773
|
+
export { DEFAULT_PALETTE, GridOverlay, ImageFontAtlas, Terminal2D, colorToPaletteIndex, getAtlasColumns, getCharGridPosition, getMaxCharCode, paletteIndexToColor };
|
|
774
|
+
export type { AtlasBlocks, BitmapFont, ImageFontAtlasConfig, RenderOptions, TerminalCell, TerminalData };
|