textmode.js 0.1.8 → 0.1.9-beta.2
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/textmode.umd.js
CHANGED
|
@@ -43,7 +43,7 @@ void main() {\r
|
|
|
43
43
|
\r
|
|
44
44
|
gl_Position = vec4(pos, 0.0, 1.0);\r
|
|
45
45
|
}\r
|
|
46
|
-
`,dA={enabled:!0,characters:" .:-=+*%@#",characterColor:[1,1,1,1],characterColorMode:"sampled",cellColor:[0,0,0,1],cellColorMode:"fixed",invert:!1,rotation:[0,0,0,255],flipHorizontally:!1,flipVertically:!1,brightnessRange:[0,255]};class H extends V{constructor(s,r,i){super(s,r,i,{...dA});n(this,"me");n(this,"pe");n(this,"_e");n(this,"ve");n(this,"be");n(this,"xe");this.me=new v(s.context,U,"precision lowp float;uniform sampler2D u_sketchTexture;uniform vec2 u_gridCellDimensions;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec2 cellCenter=(floor(v_uv*u_gridCellDimensions)+vec2(0.5))/u_gridCellDimensions;vec4 color=texture2D(u_sketchTexture,cellCenter);float brightness=dot(color.rgb,vec3(0.299,0.587,0.114));float brightnessValue=brightness*255.0;if(brightnessValue>=u_brightnessRange.x&&brightnessValue<=u_brightnessRange.y){gl_FragColor=color;}else{gl_FragColor=vec4(0.0);}}"),this.pe=new v(s.context,U,"precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_fillColor;uniform bool u_useFixedColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){if(u_useFixedColor){gl_FragColor=u_fillColor;}else{gl_FragColor=sampleColor;}}else{gl_FragColor=vec4(0.0);}}"),this.ve=new v(s.context,U,"precision lowp float;uniform sampler2D u_sampleTexture;uniform bool u_invert;uniform bool u_flipHorizontally;uniform bool u_flipVertically;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){float invertValue=u_invert ? 1.0 : 0.0;float flipHValue=u_flipHorizontally ? 1.0 : 0.0;float flipVValue=u_flipVertically ? 1.0 : 0.0;gl_FragColor=vec4(invertValue,flipHValue,flipVValue,1.0);}else{gl_FragColor=vec4(0.0);}}"),this.be=new v(s.context,U,"precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_rotationColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){gl_FragColor=u_rotationColor;}else{gl_FragColor=vec4(0.0);}}"),this._e=new v(s.context,U,"precision lowp float;uniform sampler2D u_colorSampleFramebuffer;uniform sampler2D u_charPaletteTexture;uniform vec2 u_charPaletteSize;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec4 color=texture2D(u_colorSampleFramebuffer,v_uv);if(color.a==0.0){gl_FragColor=vec4(0.0);return;}float brightness=dot(color.rgb,vec3(0.299,0.587,0.114))*255.0;vec2 range=u_brightnessRange;if(brightness<range.x||brightness>range.y){gl_FragColor=vec4(0.0);return;}float t=(brightness-range.x)/(range.y-range.x);float idx=clamp(floor(t*u_charPaletteSize.x),0.0,u_charPaletteSize.x-1.0);vec3 charColor=texture2D(u_charPaletteTexture,vec2((idx+0.5)/u_charPaletteSize.x,0.0)).rgb;gl_FragColor=vec4(charColor,1.0);}"),this.xe=this.Dt.TA(this.ne.cols,this.ne.rows)}ye(s){const r=this.ne.cols,i=this.ne.rows;this.xe.begin(),this.Dt.OA(),this.Dt.IA(this.me),this.Dt.GA("u_sketchTexture",s),this.Dt.GA("u_gridCellDimensions",[r,i]),this.Dt.GA("u_brightnessRange",this.h.brightnessRange),this.Dt.FA(0,0,r,i),this.xe.end(),this.he.begin(),this.Dt.OA(),this.Dt.IA(this.pe),this.Dt.GA("u_sampleTexture",this.xe),this.Dt.GA("u_fillColor",this.h.characterColor),this.Dt.GA("u_useFixedColor",this.h.characterColorMode==="fixed"),this.Dt.FA(0,0,r,i),this.he.end(),this.le.begin(),this.Dt.OA(),this.Dt.IA(this.pe),this.Dt.GA("u_sampleTexture",this.xe),this.Dt.GA("u_fillColor",this.h.cellColor),this.Dt.GA("u_useFixedColor",this.h.cellColorMode==="fixed"),this.Dt.FA(0,0,r,i),this.le.end(),this.De.begin(),this.Dt.OA(),this.Dt.IA(this.ve),this.Dt.GA("u_sampleTexture",this.xe),this.Dt.GA("u_invert",this.h.invert),this.Dt.GA("u_flipHorizontally",this.h.flipHorizontally),this.Dt.GA("u_flipVertically",this.h.flipVertically),this.Dt.FA(0,0,r,i),this.De.end(),this.ce.begin(),this.Dt.OA(),this.Dt.IA(this.be),this.Dt.GA("u_sampleTexture",this.xe),this.Dt.GA("u_rotationColor",this.h.rotation),this.Dt.FA(0,0,r,i),this.ce.end(),this.ae.begin(),this.Dt.OA(),this.Dt.IA(this._e),this.Dt.GA("u_colorSampleFramebuffer",this.xe),this.Dt.GA("u_charPaletteTexture",this.Pe.texture),this.Dt.GA("u_charPaletteSize",[this.Pe.colors.length,1]),this.Dt.GA("u_brightnessRange",this.h.brightnessRange),this.Dt.FA(0,0,r,i),this.ae.end()}ee(){super.ee(),this.xe.resize(this.ne.cols,this.ne.rows)}brightnessRange(s){I.C(Array.isArray(s)&&s.length===2&&s.every(r=>typeof r=="number"&&r>=0&&r<=255),"Brightness range must be an array of two numbers between 0 and 255.",{method:"brightnessRange",providedValue:s})&&(this.h.brightnessRange=s)}}const IA=Object.freeze(Object.defineProperty({__proto__:null,TextmodeBrightnessConverter:H,TextmodeConverter:G,TextmodeFeatureConverter:V},Symbol.toStringTag,{value:"Module"}));class eA{constructor(e,s,r){n(this,"Dt");n(this,"_t");n(this,"ne");n(this,"Me");n(this,"Ge");n(this,"Fe");n(this,"$e");n(this,"Ye");n(this,"ae");n(this,"he");n(this,"le");n(this,"ce");n(this,"De");this.Dt=e,this._t=s,this.ne=r,this.Ye=this.Dt.yA(W,"precision mediump float;uniform sampler2D u_characterTexture;uniform vec2 u_charsetDimensions;uniform sampler2D u_primaryColorTexture;uniform sampler2D u_secondaryColorTexture;uniform sampler2D u_transformTexture;uniform sampler2D u_asciiCharacterTexture;uniform sampler2D u_rotationTexture;uniform sampler2D u_captureTexture;uniform vec2 u_captureDimensions;uniform int u_backgroundMode;uniform vec2 u_gridCellDimensions;uniform vec2 u_gridPixelDimensions;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){vec2 adjustedCoord=gl_FragCoord.xy/u_gridPixelDimensions;vec2 gridCoord=adjustedCoord*u_gridCellDimensions;vec2 cellCoord=floor(gridCoord);vec2 charIndexTexCoord=(cellCoord+0.5)/u_gridCellDimensions;vec4 primaryColor=texture2D(u_primaryColorTexture,charIndexTexCoord);vec4 secondaryColor=texture2D(u_secondaryColorTexture,charIndexTexCoord);vec4 transformColor=texture2D(u_transformTexture,charIndexTexCoord);bool isInverted=transformColor.r>0.5;bool flipHorizontal=transformColor.g>0.5;bool flipVertical=transformColor.b>0.5;vec4 encodedIndexVec=texture2D(u_asciiCharacterTexture,charIndexTexCoord);if(encodedIndexVec.a<0.01){gl_FragColor=(u_backgroundMode==0)? vec4(0.0):texture2D(u_captureTexture,gl_FragCoord.xy/u_captureDimensions);return;}int charIndex=int(encodedIndexVec.r*255.0+0.5)+int(encodedIndexVec.g*255.0+0.5)*256;int charCol=int(mod(float(charIndex),u_charsetDimensions.x));int charRow=charIndex/int(u_charsetDimensions.x);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/u_charsetDimensions;vec4 rotationColor=texture2D(u_rotationTexture,charIndexTexCoord);float scaledAngle=rotationColor.r*255.0+rotationColor.g;float rotationAngle=(scaledAngle*360.0/255.0)*0.017453292;vec2 fractionalPart=fract(gridCoord)-0.5;if(flipHorizontal)fractionalPart.x=-fractionalPart.x;if(flipVertical)fractionalPart.y=-fractionalPart.y;fractionalPart=rotate2D(rotationAngle)*fractionalPart+0.5;vec2 cellSize=1.0/u_charsetDimensions;vec2 texCoord=charCoord+fractionalPart*cellSize;vec2 cellMax=charCoord+cellSize;if(any(lessThan(texCoord,charCoord))||any(greaterThan(texCoord,cellMax))){gl_FragColor=isInverted ? primaryColor : secondaryColor;return;}vec4 charTexel=texture2D(u_characterTexture,texCoord);if(isInverted)charTexel.rgb=1.0-charTexel.rgb;gl_FragColor=mix(secondaryColor,primaryColor,charTexel);}"),this.Ge=new H(e,s,r),this.Fe=new G(e,s,r),this.Me=[this.Ge,this.Fe],this.ae=this.Dt.TA(r.cols,r.rows),this.he=this.Dt.TA(r.cols,r.rows),this.le=this.Dt.TA(r.cols,r.rows),this.ce=this.Dt.TA(r.cols,r.rows),this.De=this.Dt.TA(r.cols,r.rows),this.$e=this.Dt.TA(this.ne.width,this.ne.height)}Te(e){for(const r of this.Me)r.options.enabled&&r instanceof V&&r.ye(e);const s=(r,i)=>{r.begin(),this.Dt.OA();for(const B of this.Me)B.options.enabled&&this.Dt.kA(i(B),0,0);r.end()};s(this.ae,r=>r.characterFramebuffer),s(this.he,r=>r.primaryColorFramebuffer),s(this.le,r=>r.secondaryColorFramebuffer),s(this.ce,r=>r.rotationFramebuffer),s(this.De,r=>r.transformFramebuffer),this.$e.begin(),this.Dt.OA(),this.Dt.IA(this.Ye),this.Dt.GA("u_characterTexture",this._t.fontFramebuffer),this.Dt.GA("u_charsetDimensions",[this._t.textureColumns,this._t.textureRows]),this.Dt.GA("u_asciiCharacterTexture",this.ae.texture),this.Dt.GA("u_primaryColorTexture",this.he.texture),this.Dt.GA("u_secondaryColorTexture",this.le.texture),this.Dt.GA("u_transformTexture",this.De.texture),this.Dt.GA("u_rotationTexture",this.ce.texture),this.Dt.GA("u_captureTexture",e.texture),this.Dt.GA("u_backgroundMode",!1),this.Dt.GA("u_captureDimensions",[e.width,e.height]),this.Dt.GA("u_gridCellDimensions",[this.ne.cols,this.ne.rows]),this.Dt.GA("u_gridPixelDimensions",[this.ne.width,this.ne.height]),this.Dt.FA(0,0,this.$e.width,this.$e.height),this.$e.end()}add(e){if(!I.C(e==="brightness"||e==="custom",'Converter type must be either "brightness" or "custom".',{method:"add",providedValue:e}))return;let s;return s=e==="brightness"?new H(this.Dt,this._t,this.ne):new G(this.Dt,this._t,this.ne),this.Me.push(s),s}remove(e){if(!I.C(e instanceof G,"Parameter must be a TextmodeConverter instance.",{method:"remove",providedValue:e}))return;const s=this.Me.indexOf(e);I.C(s!==-1,"Converter instance not found in pipeline.",{method:"remove",providedValue:e,convertersCount:this.Me.length})&&this.Me.splice(s,1)}swap(e,s){const r=(o,g)=>{if(typeof o=="number")return I.C(Number.isInteger(o)&&o>=0&&o<this.Me.length,g+" index must be a valid integer within the converter array bounds.",{method:"swap",providedValue:o,convertersCount:this.Me.length})?o:null;if(o instanceof G){const h=this.Me.indexOf(o);return I.C(h!==-1,g+" converter instance not found in pipeline.",{method:"swap",providedValue:o,convertersCount:this.Me.length})?h:null}return I.C(!1,g+" parameter must be either an integer index or a TextmodeConverter instance.",{method:"swap",providedValue:o}),null},i=r(e,"First"),B=r(s,"Second");if(i===null||B===null||!I.C(i!==B,"Cannot swap a converter with itself.",{method:"swap",firstIndex:i,secondIndex:B}))return;const E=this.Me[i];this.Me[i]=this.Me[B],this.Me[B]=E}ee(){this.$e.resize(this.ne.width,this.ne.height);const e=this.ne.cols,s=this.ne.rows;this.ae.resize(e,s),this.he.resize(e,s),this.le.resize(e,s),this.ce.resize(e,s),this.De.resize(e,s);for(const r of this.Me)r.ee()}hasEnabledConverters(){return this.Me.some(e=>e.options.enabled)}disable(){for(const e of this.Me)e.disable()}enable(){for(const e of this.Me)e.enable()}S(){for(const e of this.Me)e.S();this.ae.S(),this.he.S(),this.le.S(),this.ce.S(),this.De.S(),this.$e.S(),this.Ye.S()}get texture(){return this.$e}get characterFramebuffer(){return this.ae}get primaryColorFramebuffer(){return this.he}get secondaryColorFramebuffer(){return this.le}get rotationFramebuffer(){return this.ce}get transformFramebuffer(){return this.De}get brightness(){return this.Ge}get custom(){return this.Fe}}const fA=Q=>class extends Q{fill(e,s,r,i){this.Dt.wA(e,s,r,i)}stroke(e,s,r,i){this.Dt.fA(e,s,r,i)}strokeWeight(e){this.Dt.dA(e)}noStroke(){this.Dt.mA()}noFill(){this.Dt.pA()}rotate(e){this.Dt._A(e)}push(){this.Dt.vA()}pop(){this.Dt.bA()}rect(e,s,r=1,i=1){this.Dt.FA(e,s,r,i)}line(e,s,r,i){this.Dt.YA(e,s,r,i)}background(e,s=e,r=e,i=255){this.Dt.SA(e,s,r,i)}createShader(e,s){return this.Dt.yA(e,s)}createFilterShader(e){return this.Dt.MA(e)}shader(e){this.Dt.IA(e)}setUniform(e,s){this.Dt.GA(e,s)}};class ${Se(e){const s=e.characterFramebuffer,r=e.primaryColorFramebuffer,i=e.secondaryColorFramebuffer,B=e.transformFramebuffer,E=e.rotationFramebuffer;return s==null||s.loadPixels(),r==null||r.loadPixels(),i==null||i.loadPixels(),B==null||B.loadPixels(),E==null||E.loadPixels(),{characterPixels:(s==null?void 0:s.pixels)||new Uint8Array(0),primaryColorPixels:(r==null?void 0:r.pixels)||new Uint8Array(0),secondaryColorPixels:(i==null?void 0:i.pixels)||new Uint8Array(0),transformPixels:(B==null?void 0:B.pixels)||new Uint8Array(0),rotationPixels:(E==null?void 0:E.pixels)||new Uint8Array(0)}}Oe(e,s){return e[s]+(e[s+1]<<8)}Ue(e,s){return{r:e[s],g:e[s+1],b:e[s+2],a:e[s+3]}}}class N{ke(e,s){return new Blob([e],{type:s})}Ve(e,s,r){try{const i=this.ke(e,r),B=URL.createObjectURL(i),E=document.createElement("a");E.href=B,E.download=s,E.style.display="none",E.rel="noopener",document.body.appendChild(E),E.click(),document.body.removeChild(E),URL.revokeObjectURL(B)}catch(i){throw console.error("Failed to download file:",i),Error("File download failed: "+(i instanceof Error?i.message:"Unknown error"))}}Re(){return new Date().toISOString().slice(0,19).replace(/:/g,"-")}He(){const e=new Date;return{date:e.toISOString().split("T")[0],time:e.toTimeString().split(" ")[0].replace(/:/g,"-")}}ze(e){return e.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)}Le(){return"'textmode-export'-"+this.Re()}}class wA extends ${Je(e,s,r){const i=e[r]===255,B=e[r+1]===255,E=e[r+2]===255,o=s[r],g=s[r+1];return{isInverted:i,flipHorizontal:B,flipVertical:E,rotation:Math.round(360*(o+g/255)/255*100)/100}}je(e,s,r){return{x:e,y:s,cellX:e*r.cellWidth,cellY:s*r.cellHeight}}Ke(e,s){const r=[];let i=0;for(let B=0;B<s.rows;B++)for(let E=0;E<s.cols;E++){const o=4*i,g=this.Oe(e.characterPixels,o);let h=this.Ue(e.primaryColorPixels,o),a=this.Ue(e.secondaryColorPixels,o);const c=this.Je(e.transformPixels,e.rotationPixels,o);if(c.isInverted){const u=h;h=a,a=u}const l=this.je(E,B,s);r.push({charIndex:g,primaryColor:h,secondaryColor:a,transform:c,position:l}),i++}return r}}class pA{We(e,s){const r=e.cmap;for(const i of r.tables)if(i.format===4){for(let B=0;B<i.startCount.length;B++)if(s>=i.startCount[B]&&s<=i.endCount[B]){if(i.idRangeOffset[B]===0)return s+i.idDelta[B]&65535;{const E=i.idRangeOffset[B]/2+(s-i.startCount[B])-(i.startCount.length-B);if(E>=0&&E<i.glyphIdArray.length){const o=i.glyphIdArray[E];if(o!==0)return o+i.idDelta[B]&65535}}}}return 0}Ne(e,s,r,i,B){const E=B/e.head.unitsPerEm;return{getBoundingBox:()=>({x1:r+s.xMin*E,y1:i+-s.yMax*E,x2:r+s.xMax*E,y2:i+-s.yMin*E}),toSVG:()=>this.Ze(s,r,i,E)}}Ze(e,s,r,i){if(!e||!e.xs)return"";const{xs:B,ys:E,endPts:o,flags:g}=e;if(!(B&&E&&o&&g))return"";let h="",a=0;for(let c=0;c<o.length;c++){const l=o[c];if(!(l<a)){if(l>=a){const u=s+B[a]*i,C=r-E[a]*i;h+=`M${u.toFixed(2)},${C.toFixed(2)}`;let D=a+1;for(;D<=l;)if(1&g[D]){const p=s+B[D]*i,f=r-E[D]*i;h+=`L${p.toFixed(2)},${f.toFixed(2)}`,D++}else{const p=s+B[D]*i,f=r-E[D]*i;let w=D+1>l?a:D+1;if(1&g[w]){const b=s+B[w]*i,y=r-E[w]*i;h+=`Q${p.toFixed(2)},${f.toFixed(2)} ${b.toFixed(2)},${y.toFixed(2)}`,D=w+1}else{const b=(p+(s+B[w]*i))/2,y=(f+(r-E[w]*i))/2;h+=`Q${p.toFixed(2)},${f.toFixed(2)} ${b.toFixed(2)},${y.toFixed(2)}`,D=w}}h+="Z"}a=l+1}}return h}Xe(e,s,r,i,B){const E=e.codePointAt(0)||0,o=this.We(s,E);let g=null;return s.glyf&&s.glyf[o]!==null?g=s.glyf[o]:x&&x.T&&x.T.glyf&&x.T.glyf.VA&&(g=x.T.glyf.VA(s,o),s.glyf&&g&&(s.glyf[o]=g)),this.Ne(s,g,r,i,B)}qe(e,s,r,i,B,E,o,g){const h=r+(B-g*(o/s.head.unitsPerEm))/2,a=i+(E+.7*o)/2;return this.Xe(e,s,h,a,o).toSVG()||null}}class mA{constructor(){n(this,"As");this.As=new pA}ts(e){return`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
46
|
+
`,dA={enabled:!0,characters:" .:-=+*%@#",characterColor:[1,1,1,1],characterColorMode:"sampled",cellColor:[0,0,0,1],cellColorMode:"fixed",invert:!1,rotation:[0,0,0,255],flipHorizontally:!1,flipVertically:!1,brightnessRange:[0,255]};class H extends V{constructor(s,r,i){super(s,r,i,{...dA});n(this,"me");n(this,"pe");n(this,"_e");n(this,"ve");n(this,"be");n(this,"xe");this.me=new v(s.context,U,"precision lowp float;uniform sampler2D u_sketchTexture;uniform vec2 u_gridCellDimensions;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec2 cellCenter=(floor(v_uv*u_gridCellDimensions)+vec2(0.5))/u_gridCellDimensions;vec4 color=texture2D(u_sketchTexture,cellCenter);float brightness=dot(color.rgb,vec3(0.299,0.587,0.114));float brightnessValue=brightness*255.0;if(brightnessValue>=u_brightnessRange.x&&brightnessValue<=u_brightnessRange.y){gl_FragColor=color;}else{gl_FragColor=vec4(0.0);}}"),this.pe=new v(s.context,U,"precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_fillColor;uniform bool u_useFixedColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){if(u_useFixedColor){gl_FragColor=u_fillColor;}else{gl_FragColor=sampleColor;}}else{gl_FragColor=vec4(0.0);}}"),this.ve=new v(s.context,U,"precision lowp float;uniform sampler2D u_sampleTexture;uniform bool u_invert;uniform bool u_flipHorizontally;uniform bool u_flipVertically;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){float invertValue=u_invert ? 1.0 : 0.0;float flipHValue=u_flipHorizontally ? 1.0 : 0.0;float flipVValue=u_flipVertically ? 1.0 : 0.0;gl_FragColor=vec4(invertValue,flipHValue,flipVValue,1.0);}else{gl_FragColor=vec4(0.0);}}"),this.be=new v(s.context,U,"precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_rotationColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){gl_FragColor=u_rotationColor;}else{gl_FragColor=vec4(0.0);}}"),this._e=new v(s.context,U,"precision lowp float;uniform sampler2D u_colorSampleFramebuffer;uniform sampler2D u_charPaletteTexture;uniform vec2 u_charPaletteSize;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec4 color=texture2D(u_colorSampleFramebuffer,v_uv);if(color.a==0.0){gl_FragColor=vec4(0.0);return;}float brightness=dot(color.rgb,vec3(0.299,0.587,0.114))*255.0;vec2 range=u_brightnessRange;if(brightness<range.x||brightness>range.y){gl_FragColor=vec4(0.0);return;}float t=(brightness-range.x)/(range.y-range.x);float idx=clamp(floor(t*u_charPaletteSize.x),0.0,u_charPaletteSize.x-1.0);vec3 charColor=texture2D(u_charPaletteTexture,vec2((idx+0.5)/u_charPaletteSize.x,0.0)).rgb;gl_FragColor=vec4(charColor,1.0);}"),this.xe=this.Dt.TA(this.ne.cols,this.ne.rows)}ye(s){const r=this.ne.cols,i=this.ne.rows;this.xe.begin(),this.Dt.OA(),this.Dt.IA(this.me),this.Dt.GA("u_sketchTexture",s),this.Dt.GA("u_gridCellDimensions",[r,i]),this.Dt.GA("u_brightnessRange",this.h.brightnessRange),this.Dt.FA(0,0,r,i),this.xe.end(),this.he.begin(),this.Dt.OA(),this.Dt.IA(this.pe),this.Dt.GA("u_sampleTexture",this.xe),this.Dt.GA("u_fillColor",this.h.characterColor),this.Dt.GA("u_useFixedColor",this.h.characterColorMode==="fixed"),this.Dt.FA(0,0,r,i),this.he.end(),this.le.begin(),this.Dt.OA(),this.Dt.IA(this.pe),this.Dt.GA("u_sampleTexture",this.xe),this.Dt.GA("u_fillColor",this.h.cellColor),this.Dt.GA("u_useFixedColor",this.h.cellColorMode==="fixed"),this.Dt.FA(0,0,r,i),this.le.end(),this.De.begin(),this.Dt.OA(),this.Dt.IA(this.ve),this.Dt.GA("u_sampleTexture",this.xe),this.Dt.GA("u_invert",this.h.invert),this.Dt.GA("u_flipHorizontally",this.h.flipHorizontally),this.Dt.GA("u_flipVertically",this.h.flipVertically),this.Dt.FA(0,0,r,i),this.De.end(),this.ce.begin(),this.Dt.OA(),this.Dt.IA(this.be),this.Dt.GA("u_sampleTexture",this.xe),this.Dt.GA("u_rotationColor",this.h.rotation),this.Dt.FA(0,0,r,i),this.ce.end(),this.ae.begin(),this.Dt.OA(),this.Dt.IA(this._e),this.Dt.GA("u_colorSampleFramebuffer",this.xe),this.Dt.GA("u_charPaletteTexture",this.Pe.texture),this.Dt.GA("u_charPaletteSize",[this.Pe.colors.length,1]),this.Dt.GA("u_brightnessRange",this.h.brightnessRange),this.Dt.FA(0,0,r,i),this.ae.end()}ee(){super.ee(),this.xe.resize(this.ne.cols,this.ne.rows)}brightnessRange(s){I.C(Array.isArray(s)&&s.length===2&&s.every(r=>typeof r=="number"&&r>=0&&r<=255),"Brightness range must be an array of two numbers between 0 and 255.",{method:"brightnessRange",providedValue:s})&&(this.h.brightnessRange=s)}}const IA=Object.freeze(Object.defineProperty({__proto__:null,TextmodeBrightnessConverter:H,TextmodeConverter:G,TextmodeFeatureConverter:V},Symbol.toStringTag,{value:"Module"}));class eA{constructor(e,s,r){n(this,"Dt");n(this,"_t");n(this,"ne");n(this,"Me");n(this,"Ge");n(this,"Fe");n(this,"$e");n(this,"Ye");n(this,"ae");n(this,"he");n(this,"le");n(this,"ce");n(this,"De");this.Dt=e,this._t=s,this.ne=r,this.Ye=this.Dt.yA(W,"precision mediump float;uniform sampler2D u_characterTexture;uniform vec2 u_charsetDimensions;uniform sampler2D u_primaryColorTexture;uniform sampler2D u_secondaryColorTexture;uniform sampler2D u_transformTexture;uniform sampler2D u_asciiCharacterTexture;uniform sampler2D u_rotationTexture;uniform sampler2D u_captureTexture;uniform vec2 u_captureDimensions;uniform int u_backgroundMode;uniform vec2 u_gridCellDimensions;uniform vec2 u_gridPixelDimensions;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){vec2 adjustedCoord=gl_FragCoord.xy/u_gridPixelDimensions;vec2 gridCoord=adjustedCoord*u_gridCellDimensions;vec2 cellCoord=floor(gridCoord);vec2 charIndexTexCoord=(cellCoord+0.5)/u_gridCellDimensions;vec4 primaryColor=texture2D(u_primaryColorTexture,charIndexTexCoord);vec4 secondaryColor=texture2D(u_secondaryColorTexture,charIndexTexCoord);vec4 transformColor=texture2D(u_transformTexture,charIndexTexCoord);bool isInverted=transformColor.r>0.5;bool flipHorizontal=transformColor.g>0.5;bool flipVertical=transformColor.b>0.5;vec4 encodedIndexVec=texture2D(u_asciiCharacterTexture,charIndexTexCoord);if(encodedIndexVec.a<0.01){gl_FragColor=(u_backgroundMode==0)? vec4(0.0):texture2D(u_captureTexture,gl_FragCoord.xy/u_captureDimensions);return;}int charIndex=int(encodedIndexVec.r*255.0+0.5)+int(encodedIndexVec.g*255.0+0.5)*256;int charCol=int(mod(float(charIndex),u_charsetDimensions.x));int charRow=charIndex/int(u_charsetDimensions.x);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/u_charsetDimensions;vec4 rotationColor=texture2D(u_rotationTexture,charIndexTexCoord);float scaledAngle=rotationColor.r*255.0+rotationColor.g;float rotationAngle=(scaledAngle*360.0/255.0)*0.017453292;vec2 fractionalPart=fract(gridCoord)-0.5;if(flipHorizontal)fractionalPart.x=-fractionalPart.x;if(flipVertical)fractionalPart.y=-fractionalPart.y;fractionalPart=rotate2D(rotationAngle)*fractionalPart+0.5;vec2 cellSize=1.0/u_charsetDimensions;vec2 texCoord=charCoord+fractionalPart*cellSize;vec2 cellMax=charCoord+cellSize;if(any(lessThan(texCoord,charCoord))||any(greaterThan(texCoord,cellMax))){gl_FragColor=isInverted ? primaryColor : secondaryColor;return;}vec4 charTexel=texture2D(u_characterTexture,texCoord);if(isInverted)charTexel.rgb=1.0-charTexel.rgb;gl_FragColor=mix(secondaryColor,primaryColor,charTexel);}"),this.Ge=new H(e,s,r),this.Fe=new G(e,s,r),this.Me=[this.Ge,this.Fe],this.ae=this.Dt.TA(r.cols,r.rows),this.he=this.Dt.TA(r.cols,r.rows),this.le=this.Dt.TA(r.cols,r.rows),this.ce=this.Dt.TA(r.cols,r.rows),this.De=this.Dt.TA(r.cols,r.rows),this.$e=this.Dt.TA(this.ne.width,this.ne.height)}Te(e){for(const r of this.Me)r.options.enabled&&r instanceof V&&r.ye(e);const s=(r,i)=>{r.begin(),this.Dt.OA();for(const B of this.Me)B.options.enabled&&this.Dt.kA(i(B),0,0);r.end()};s(this.ae,r=>r.characterFramebuffer),s(this.he,r=>r.primaryColorFramebuffer),s(this.le,r=>r.secondaryColorFramebuffer),s(this.ce,r=>r.rotationFramebuffer),s(this.De,r=>r.transformFramebuffer),this.$e.begin(),this.Dt.OA(),this.Dt.IA(this.Ye),this.Dt.GA("u_characterTexture",this._t.fontFramebuffer),this.Dt.GA("u_charsetDimensions",[this._t.textureColumns,this._t.textureRows]),this.Dt.GA("u_asciiCharacterTexture",this.ae.texture),this.Dt.GA("u_primaryColorTexture",this.he.texture),this.Dt.GA("u_secondaryColorTexture",this.le.texture),this.Dt.GA("u_transformTexture",this.De.texture),this.Dt.GA("u_rotationTexture",this.ce.texture),this.Dt.GA("u_captureTexture",e.texture),this.Dt.GA("u_backgroundMode",!1),this.Dt.GA("u_captureDimensions",[e.width,e.height]),this.Dt.GA("u_gridCellDimensions",[this.ne.cols,this.ne.rows]),this.Dt.GA("u_gridPixelDimensions",[this.ne.width,this.ne.height]),this.Dt.FA(0,0,this.$e.width,this.$e.height),this.$e.end()}add(e){if(!I.C(e==="brightness"||e==="custom",'Converter type must be either "brightness" or "custom".',{method:"add",providedValue:e}))return;let s;return s=e==="brightness"?new H(this.Dt,this._t,this.ne):new G(this.Dt,this._t,this.ne),this.Me.push(s),s}remove(e){if(!I.C(e instanceof G,"Parameter must be a TextmodeConverter instance.",{method:"remove",providedValue:e}))return;const s=this.Me.indexOf(e);I.C(s!==-1,"Converter instance not found in pipeline.",{method:"remove",providedValue:e,convertersCount:this.Me.length})&&this.Me.splice(s,1)}swap(e,s){const r=(o,g)=>{if(typeof o=="number")return I.C(Number.isInteger(o)&&o>=0&&o<this.Me.length,g+" index must be a valid integer within the converter array bounds.",{method:"swap",providedValue:o,convertersCount:this.Me.length})?o:null;if(o instanceof G){const h=this.Me.indexOf(o);return I.C(h!==-1,g+" converter instance not found in pipeline.",{method:"swap",providedValue:o,convertersCount:this.Me.length})?h:null}return I.C(!1,g+" parameter must be either an integer index or a TextmodeConverter instance.",{method:"swap",providedValue:o}),null},i=r(e,"First"),B=r(s,"Second");if(i===null||B===null||!I.C(i!==B,"Cannot swap a converter with itself.",{method:"swap",firstIndex:i,secondIndex:B}))return;const E=this.Me[i];this.Me[i]=this.Me[B],this.Me[B]=E}ee(){this.$e.resize(this.ne.width,this.ne.height);const e=this.ne.cols,s=this.ne.rows;this.ae.resize(e,s),this.he.resize(e,s),this.le.resize(e,s),this.ce.resize(e,s),this.De.resize(e,s);for(const r of this.Me)r.ee()}hasEnabledConverters(){return this.Me.some(e=>e.options.enabled)}disable(){for(const e of this.Me)e.disable()}enable(){for(const e of this.Me)e.enable()}S(){for(const e of this.Me)e.S();this.ae.S(),this.he.S(),this.le.S(),this.ce.S(),this.De.S(),this.$e.S(),this.Ye.S()}get texture(){return this.$e}get characterFramebuffer(){return this.ae}get primaryColorFramebuffer(){return this.he}get secondaryColorFramebuffer(){return this.le}get rotationFramebuffer(){return this.ce}get transformFramebuffer(){return this.De}get brightness(){return this.Ge}get custom(){return this.Fe}}const fA=Q=>class extends Q{fill(e,s,r,i){this.Dt.wA(e,s,r,i)}stroke(e,s,r,i){this.Dt.fA(e,s,r,i)}strokeWeight(e){this.Dt.dA(e)}noStroke(){this.Dt.mA()}noFill(){this.Dt.pA()}rotate(e){this.Dt._A(e)}push(){this.Dt.vA()}pop(){this.Dt.bA()}rect(e,s,r=1,i=1){this.Dt.FA(e,s,r,i)}line(e,s,r,i){this.Dt.YA(e,s,r,i)}background(e,s=e,r=e,i=255){this.Dt.SA(e,s,r,i)}createShader(e,s){return this.Dt.yA(e,s)}createFilterShader(e){return this.Dt.MA(e)}shader(e){this.Dt.IA(e)}setUniform(e,s){this.Dt.GA(e,s)}image(e,s,r,i,B){this.Dt.kA(e,s,r,i,B)}clear(){this.Dt.OA()}createFramebuffer(e,s,r={}){return this.Dt.TA(e,s,r)}};class ${Se(e){const s=e.characterFramebuffer,r=e.primaryColorFramebuffer,i=e.secondaryColorFramebuffer,B=e.transformFramebuffer,E=e.rotationFramebuffer;return s==null||s.loadPixels(),r==null||r.loadPixels(),i==null||i.loadPixels(),B==null||B.loadPixels(),E==null||E.loadPixels(),{characterPixels:(s==null?void 0:s.pixels)||new Uint8Array(0),primaryColorPixels:(r==null?void 0:r.pixels)||new Uint8Array(0),secondaryColorPixels:(i==null?void 0:i.pixels)||new Uint8Array(0),transformPixels:(B==null?void 0:B.pixels)||new Uint8Array(0),rotationPixels:(E==null?void 0:E.pixels)||new Uint8Array(0)}}Oe(e,s){return e[s]+(e[s+1]<<8)}Ue(e,s){return{r:e[s],g:e[s+1],b:e[s+2],a:e[s+3]}}}class N{ke(e,s){return new Blob([e],{type:s})}Ve(e,s,r){try{const i=this.ke(e,r),B=URL.createObjectURL(i),E=document.createElement("a");E.href=B,E.download=s,E.style.display="none",E.rel="noopener",document.body.appendChild(E),E.click(),document.body.removeChild(E),URL.revokeObjectURL(B)}catch(i){throw console.error("Failed to download file:",i),Error("File download failed: "+(i instanceof Error?i.message:"Unknown error"))}}Re(){return new Date().toISOString().slice(0,19).replace(/:/g,"-")}He(){const e=new Date;return{date:e.toISOString().split("T")[0],time:e.toTimeString().split(" ")[0].replace(/:/g,"-")}}ze(e){return e.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)}Le(){return"'textmode-export'-"+this.Re()}}class wA extends ${Je(e,s,r){const i=e[r]===255,B=e[r+1]===255,E=e[r+2]===255,o=s[r],g=s[r+1];return{isInverted:i,flipHorizontal:B,flipVertical:E,rotation:Math.round(360*(o+g/255)/255*100)/100}}je(e,s,r){return{x:e,y:s,cellX:e*r.cellWidth,cellY:s*r.cellHeight}}Ke(e,s){const r=[];let i=0;for(let B=0;B<s.rows;B++)for(let E=0;E<s.cols;E++){const o=4*i,g=this.Oe(e.characterPixels,o);let h=this.Ue(e.primaryColorPixels,o),a=this.Ue(e.secondaryColorPixels,o);const c=this.Je(e.transformPixels,e.rotationPixels,o);if(c.isInverted){const u=h;h=a,a=u}const l=this.je(E,B,s);r.push({charIndex:g,primaryColor:h,secondaryColor:a,transform:c,position:l}),i++}return r}}class pA{We(e,s){const r=e.cmap;for(const i of r.tables)if(i.format===4){for(let B=0;B<i.startCount.length;B++)if(s>=i.startCount[B]&&s<=i.endCount[B]){if(i.idRangeOffset[B]===0)return s+i.idDelta[B]&65535;{const E=i.idRangeOffset[B]/2+(s-i.startCount[B])-(i.startCount.length-B);if(E>=0&&E<i.glyphIdArray.length){const o=i.glyphIdArray[E];if(o!==0)return o+i.idDelta[B]&65535}}}}return 0}Ne(e,s,r,i,B){const E=B/e.head.unitsPerEm;return{getBoundingBox:()=>({x1:r+s.xMin*E,y1:i+-s.yMax*E,x2:r+s.xMax*E,y2:i+-s.yMin*E}),toSVG:()=>this.Ze(s,r,i,E)}}Ze(e,s,r,i){if(!e||!e.xs)return"";const{xs:B,ys:E,endPts:o,flags:g}=e;if(!(B&&E&&o&&g))return"";let h="",a=0;for(let c=0;c<o.length;c++){const l=o[c];if(!(l<a)){if(l>=a){const u=s+B[a]*i,C=r-E[a]*i;h+=`M${u.toFixed(2)},${C.toFixed(2)}`;let D=a+1;for(;D<=l;)if(1&g[D]){const p=s+B[D]*i,f=r-E[D]*i;h+=`L${p.toFixed(2)},${f.toFixed(2)}`,D++}else{const p=s+B[D]*i,f=r-E[D]*i;let w=D+1>l?a:D+1;if(1&g[w]){const b=s+B[w]*i,y=r-E[w]*i;h+=`Q${p.toFixed(2)},${f.toFixed(2)} ${b.toFixed(2)},${y.toFixed(2)}`,D=w+1}else{const b=(p+(s+B[w]*i))/2,y=(f+(r-E[w]*i))/2;h+=`Q${p.toFixed(2)},${f.toFixed(2)} ${b.toFixed(2)},${y.toFixed(2)}`,D=w}}h+="Z"}a=l+1}}return h}Xe(e,s,r,i,B){const E=e.codePointAt(0)||0,o=this.We(s,E);let g=null;return s.glyf&&s.glyf[o]!==null?g=s.glyf[o]:x&&x.T&&x.T.glyf&&x.T.glyf.VA&&(g=x.T.glyf.VA(s,o),s.glyf&&g&&(s.glyf[o]=g)),this.Ne(s,g,r,i,B)}qe(e,s,r,i,B,E,o,g){const h=r+(B-g*(o/s.head.unitsPerEm))/2,a=i+(E+.7*o)/2;return this.Xe(e,s,h,a,o).toSVG()||null}}class mA{constructor(){n(this,"As");this.As=new pA}ts(e){return`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
47
47
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
48
48
|
<svg width="${e.width}" height="${e.height}" viewBox="0 0 ${e.width} ${e.height}"
|
|
49
49
|
xmlns="http://www.w3.org/2000/svg" version="1.1">
|
|
@@ -61,4 +61,4 @@ void main() {\r
|
|
|
61
61
|
<g id="ascii-cells">`;for(const E of e)B+=this.Es(E,s,r,i);return B+=this.es(),B}ns(e){return e.replace(/<path[^>]*d=""[^>]*\/>/g,"").replace(/\n\s*\n/g,`
|
|
62
62
|
`).replace(/[ \t]+$/gm,"")}}class xA extends N{hs(e){return this.ke(e,"image/svg+xml;charset=utf-8")}ls(e,s){this.Ve(e,this.ze(s)+".svg","image/svg+xml;charset=utf-8")}cs(e,s){this.ls(e,s||this.Le())}}class sA{constructor(){n(this,"Ds");n(this,"Cs");n(this,"us");this.Ds=new wA,this.Cs=new mA,this.us=new xA}Ps(e){return{includeBackgroundRectangles:e.includeBackgroundRectangles??!0,drawMode:e.drawMode??"fill",strokeWidth:e.strokeWidth??1,backgroundColor:e.backgroundColor??[0,0,0,0]}}Is(e,s={}){const r=this.Ps(s),i=this.Ds.Se(e.pipeline),B=this.Ds.Ke(i,e.grid),E=this.Cs.gs(B,e.grid,e.font,r);return this.Cs.ns(E)}cs(e,s={}){const r=this.Is(e,s),i=s.filename||this.us.Le();this.us.cs(r,i)}}class bA extends ${ws(e,s,r,i=" "){var o;const B=[];let E=0;for(let g=0;g<s.rows;g++){const h=[];for(let a=0;a<s.cols;a++){const c=4*E,l=this.Oe(e.characterPixels,c),u=((o=r.characters[l])==null?void 0:o.character)||i;h.push(u),E++}B.push(h)}return B}}class vA{fs(e,s){const r=[];for(const B of e){let E=B.join("");s.preserveTrailingSpaces||(E=E.replace(/\s+$/,"")),r.push(E)}const i=s.lineEnding==="crlf"?`\r
|
|
63
63
|
`:`
|
|
64
|
-
`;return r.join(i)}}class yA extends N{ds(e,s){const r=this.ps(s);this.Ve(e,r,"text/plain;charset=utf-8")}ps(e){let s=this.ze(e);return s===".txt"||s.length<=4?this.Le():s}}class rA{constructor(){n(this,"Ds");n(this,"Cs");n(this,"us");this.Ds=new bA,this.Cs=new vA,this.us=new yA}Ps(e){return{preserveTrailingSpaces:e.preserveTrailingSpaces??!1,lineEnding:e.lineEnding??"lf",emptyCharacter:e.emptyCharacter??" "}}_s(e,s={}){const r=this.Ps(s),i=this.Ds.Se(e.pipeline),B=this.Ds.ws(i,e.grid,e.font,r.emptyCharacter);return this.Cs.fs(B,r)}ds(e,s={}){const r=this._s(e,s),i=s.filename||this.us.Le();this.us.ds(r,i)}}class _A extends ${vs(e,s=1,r="transparent"){const i=e.canvas;if(s===1&&r==="transparent")return i;const B=document.createElement("canvas"),E=B.getContext("2d"),o=Math.round(i.width*s),g=Math.round(i.height*s);return B.width=o,B.height=g,r!=="transparent"&&(E.fillStyle=r,E.fillRect(0,0,o,g)),E.imageSmoothingEnabled=!1,E.drawImage(i,0,0,i.width,i.height,0,0,o,g),B}}class MA{bs(e,s){const r=this.Ms(s.format);return s.format==="png"?e.toDataURL(r):e.toDataURL(r,s.quality)}async Gs(e,s){return new Promise((r,i)=>{const B=this.Ms(s.format),E=o=>{o?r(o):i(Error(`Failed to generate ${s.format.toUpperCase()} blob`))};s.format==="png"?e.toBlob(E,B):e.toBlob(E,B,s.quality)})}Ms(e){switch(e){case"png":return"image/png";case"jpg":return"image/jpeg";case"webp":return"image/webp";default:throw Error("Unsupported image format: "+e)}}}const TA={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},iA={png:".png",jpg:".jpg",webp:".webp"};class GA extends N{Fs(e,s,r){this.$s(e,this.ze(s)+iA[r])}$s(e,s){const r=URL.createObjectURL(e);try{const i=document.createElement("a");i.href=r,i.download=s,i.style.display="none",i.rel="noopener",document.body.appendChild(i),i.click(),document.body.removeChild(i)}finally{URL.revokeObjectURL(r)}}Ys(e){return e in TA&&e in iA}}class RA{constructor(){n(this,"Ds");n(this,"Cs");n(this,"us");this.Ds=new _A,this.Cs=new MA,this.us=new GA}Ps(e){return{format:e.format??"png",quality:e.quality??1,scale:e.scale??1,backgroundColor:e.backgroundColor??"transparent"}}Ts(e){if(console.log("Validating image export options:",e),!this.us.Ys(e.format))throw Error(`Saving '${e.format}' files is not supported`);if(e.quality<0||e.quality>1)throw Error("Image quality must be between 0.0 and 1.0");if(e.scale<=0)throw Error("Scale factor must be greater than 0");e.scale>10&&console.warn("Large scale factors may result in very large files and slow performance"),e.format==="jpg"&&e.backgroundColor==="transparent"&&(e.backgroundColor="black")}Ss(e,s={}){const r=this.Ps(s);if(this.Ts(r),r.scale===1&&r.backgroundColor==="transparent")return this.Cs.bs(e.canvas,r);const i=this.Ds.vs(e,r.scale,r.backgroundColor);return this.Cs.bs(i,r)}async Gs(e,s={}){const r=this.Ps(s);if(this.Ts(r),r.scale===1&&r.backgroundColor==="transparent")return await this.Cs.Gs(e.canvas,r);const i=this.Ds.vs(e,r.scale,r.backgroundColor);return await this.Cs.Gs(i,r)}async Fs(e,s={}){const r=await this.Gs(e,s),i=s.format??"png",B=s.filename||this.us.Le();this.us.Fs(r,B,i)}}const FA=Q=>class extends Q{toString(e={}){return new rA()._s({pipeline:this.Os,grid:this.ne,font:this._t},e)}saveStrings(e={}){new rA().ds({pipeline:this.Os,grid:this.ne,font:this._t},e)}toSVG(e={}){return new sA().Is(this,e)}saveSVG(e={}){new sA().cs(this,e)}async saveCanvas(e,s="png",r={}){await new RA().Fs(this.Wt,{...r,filename:e,format:s})}},UA=Q=>class extends Q{async loadFont(e){return this._t.Ht(e).then(()=>{const s=this._t.maxGlyphDimensions;this.ne.qt(s.width,s.height),this.Os.ee()})}fontSize(e){if(!I.C(typeof e=="number"&&e>0,"Font size must be a positive number greater than 0.",{method:"fontSize",providedValue:e})||this._t.fontSize===e)return;this._t.Rt(e);const s=this._t.maxGlyphDimensions;this.ne.qt(s.width,s.height),this.Os.ee(),this.Dt.UA()}},YA=Q=>class extends Q{addConverter(e){return this.Os.add(e)}removeConverter(e){this.Os.remove(e)}};class SA{constructor(){n(this,"Dt");n(this,"_t");n(this,"Os");n(this,"Wt");n(this,"ne")}}class z extends function(s,...r){return r.reduce((i,B)=>B(i),s)}(SA,fA,FA,UA,YA){constructor(s=null,r={}){super();n(this,"re");n(this,"Us");n(this,"ie");n(this,"ks");n(this,"Vs");n(this,"Rs",null);n(this,"Hs",0);n(this,"zs");n(this,"Ls",!0);n(this,"Js",0);n(this,"js",0);n(this,"Ks",0);n(this,"Ws",[]);n(this,"Ns",10);n(this,"Zs",!1);n(this,"Xs",!1);n(this,"qs",()=>{});n(this,"Ar",()=>{});n(this,"tr");this.re=s,this.Xs=s===null,this.ks=r.renderMode??"auto",this.Vs=r.frameRate??60,this.zs=1e3/this.Vs}static async create(s=null,r={}){const i=new this(s,r),B=i.Xs?r:void 0;let E,o;i.Wt=new tA(i.re,i.Xs,B),i.Dt=new QA(i.Wt.ge()),i.Xs?(E=r.width||800,o=r.height||600):(E=i.Wt.width||800,o=i.Wt.height||600),i.Us=i.Dt.TA(E,o),i._t=new q(i.Dt,r.fontSize??16),await i._t.Ut(r.fontSource);const g=i._t.maxGlyphDimensions;return i.ne=new AA(i.Wt.canvas,g.width,g.height),i.Os=new eA(i.Dt,i._t,i.ne),i.er(),i.sr(),i}er(){this.tr=()=>{this.Xs?this.Ar():this.rr()},window.addEventListener("resize",this.tr),window.ResizeObserver&&this.re&&!this.Xs&&(this.ie=new ResizeObserver(()=>{this.rr()}),this.ie.observe(this.re))}render(){this.Br(),this.Ks++,this.Zs?console.warn("Cannot render: Required resources have been disposed"):(this.Xs?(this.Us.begin(),this.qs(),this.Us.end()):this.Us.update(this.re),this.Os.hasEnabledConverters()?(this.Os.Te(this.Us),this.Dt.SA(0),this.Dt.kA(this.Os.texture,this.ne.offsetX,this.ne.offsetY,this.Os.texture.width,this.Os.texture.height)):(this.Dt.OA(),this.Dt.kA(this.Us,this.ne.offsetX,this.ne.offsetY,this.Us.width,this.Us.height)))}rr(){this.Wt.ee(),this.Us.resize(this.Wt.width,this.Wt.height),this.ne.ee(),this.Os.ee(),this.Dt.UA(),this.ks!=="manual"&&this.render()}sr(){if(this.ks!=="auto"||!this.Ls)return;this.Hs=performance.now();const s=r=>{if(!this.Ls)return void(this.Rs=null);const i=r-this.Hs;i>=this.zs&&(this.render(),this.Hs=r-i%this.zs),this.Ls&&(this.Rs=requestAnimationFrame(s))};this.Rs=requestAnimationFrame(s)}Br(){const s=performance.now();if(this.js>0){const r=s-this.js;this.Ws.push(r),this.Ws.length>this.Ns&&this.Ws.shift();const i=this.Ws.reduce((B,E)=>B+E,0)/this.Ws.length;this.Js=1e3/i}this.js=s}ir(){this.Rs&&(cancelAnimationFrame(this.Rs),this.Rs=null)}renderMode(s){this.ks!==s&&(this.ir(),this.ks=s,s==="auto"&&this.Ls&&this.sr())}frameRate(s){if(s===void 0)return this.Js;this.Vs=s,this.zs=1e3/s,this.ks==="auto"&&this.Ls&&(this.ir(),this.sr())}noLoop(){this.Ls&&(this.Ls=!1,this.Rs&&(cancelAnimationFrame(this.Rs),this.Rs=null))}loop(){this.Ls||(this.Ls=!0,this.ks==="auto"&&this.sr())}redraw(s=1){if(I.C(typeof s=="number"&&s>0&&Number.isInteger(s),"Redraw count must be a positive integer.",{method:"redraw",providedValue:s}))for(let r=0;r<s;r++)this.render()}isLooping(){return this.ks==="auto"&&this.Ls}draw(s){this.qs=s}windowResized(s){this.Ar=s}resizeCanvas(s,r){this.Xs&&(this.Wt.ee(s,r),this.Us.resize(this.Wt.width,this.Wt.height),this.ne.ee(),this.Os.ee(),this.Dt.UA(),this.ks!=="manual"&&this.render())}destroy(){this.Zs||(this.ir(),window.removeEventListener("resize",this.tr),this.ie&&this.ie.disconnect(),this.Os.S(),this._t.S(),this.Us.S(),this.Dt.S(),this.Zs=!0)}get grid(){return this.ne}get font(){return this._t}get mode(){return this.ks}get pipeline(){return this.Os}get frameCount(){return this.Ks}set frameCount(s){this.Ks=s}get width(){return this.Wt.width}get height(){return this.Wt.height}get canvas(){return this.Wt}get isDisposed(){return this.Zs}}class Y{constructor(){throw new P("Textmode is a static class and cannot be instantiated.")}static async create(e,s={}){if(!(e==null||e instanceof HTMLCanvasElement||e instanceof HTMLVideoElement||typeof e=="object"))throw new P("First parameter must be HTMLCanvasElement, HTMLVideoElement, or options object.");if(typeof s!="object")throw new P("Second parameter must be an options object.");if(e instanceof HTMLCanvasElement||e instanceof HTMLVideoElement)return z.create(e,s);{const r=e||{};return z.create(null,r)}}static setErrorLevel(e){I.u(e)}static get version(){return"0.1.
|
|
64
|
+
`;return r.join(i)}}class yA extends N{ds(e,s){const r=this.ps(s);this.Ve(e,r,"text/plain;charset=utf-8")}ps(e){let s=this.ze(e);return s===".txt"||s.length<=4?this.Le():s}}class rA{constructor(){n(this,"Ds");n(this,"Cs");n(this,"us");this.Ds=new bA,this.Cs=new vA,this.us=new yA}Ps(e){return{preserveTrailingSpaces:e.preserveTrailingSpaces??!1,lineEnding:e.lineEnding??"lf",emptyCharacter:e.emptyCharacter??" "}}_s(e,s={}){const r=this.Ps(s),i=this.Ds.Se(e.pipeline),B=this.Ds.ws(i,e.grid,e.font,r.emptyCharacter);return this.Cs.fs(B,r)}ds(e,s={}){const r=this._s(e,s),i=s.filename||this.us.Le();this.us.ds(r,i)}}class _A extends ${vs(e,s=1,r="transparent"){const i=e.canvas;if(s===1&&r==="transparent")return i;const B=document.createElement("canvas"),E=B.getContext("2d"),o=Math.round(i.width*s),g=Math.round(i.height*s);return B.width=o,B.height=g,r!=="transparent"&&(E.fillStyle=r,E.fillRect(0,0,o,g)),E.imageSmoothingEnabled=!1,E.drawImage(i,0,0,i.width,i.height,0,0,o,g),B}}class MA{bs(e,s){const r=this.Ms(s.format);return s.format==="png"?e.toDataURL(r):e.toDataURL(r,s.quality)}async Gs(e,s){return new Promise((r,i)=>{const B=this.Ms(s.format),E=o=>{o?r(o):i(Error(`Failed to generate ${s.format.toUpperCase()} blob`))};s.format==="png"?e.toBlob(E,B):e.toBlob(E,B,s.quality)})}Ms(e){switch(e){case"png":return"image/png";case"jpg":return"image/jpeg";case"webp":return"image/webp";default:throw Error("Unsupported image format: "+e)}}}const TA={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},iA={png:".png",jpg:".jpg",webp:".webp"};class GA extends N{Fs(e,s,r){this.$s(e,this.ze(s)+iA[r])}$s(e,s){const r=URL.createObjectURL(e);try{const i=document.createElement("a");i.href=r,i.download=s,i.style.display="none",i.rel="noopener",document.body.appendChild(i),i.click(),document.body.removeChild(i)}finally{URL.revokeObjectURL(r)}}Ys(e){return e in TA&&e in iA}}class RA{constructor(){n(this,"Ds");n(this,"Cs");n(this,"us");this.Ds=new _A,this.Cs=new MA,this.us=new GA}Ps(e){return{format:e.format??"png",quality:e.quality??1,scale:e.scale??1,backgroundColor:e.backgroundColor??"transparent"}}Ts(e){if(console.log("Validating image export options:",e),!this.us.Ys(e.format))throw Error(`Saving '${e.format}' files is not supported`);if(e.quality<0||e.quality>1)throw Error("Image quality must be between 0.0 and 1.0");if(e.scale<=0)throw Error("Scale factor must be greater than 0");e.scale>10&&console.warn("Large scale factors may result in very large files and slow performance"),e.format==="jpg"&&e.backgroundColor==="transparent"&&(e.backgroundColor="black")}Ss(e,s={}){const r=this.Ps(s);if(this.Ts(r),r.scale===1&&r.backgroundColor==="transparent")return this.Cs.bs(e.canvas,r);const i=this.Ds.vs(e,r.scale,r.backgroundColor);return this.Cs.bs(i,r)}async Gs(e,s={}){const r=this.Ps(s);if(this.Ts(r),r.scale===1&&r.backgroundColor==="transparent")return await this.Cs.Gs(e.canvas,r);const i=this.Ds.vs(e,r.scale,r.backgroundColor);return await this.Cs.Gs(i,r)}async Fs(e,s={}){const r=await this.Gs(e,s),i=s.format??"png",B=s.filename||this.us.Le();this.us.Fs(r,B,i)}}const FA=Q=>class extends Q{toString(e={}){return new rA()._s({pipeline:this.Os,grid:this.ne,font:this._t},e)}saveStrings(e={}){new rA().ds({pipeline:this.Os,grid:this.ne,font:this._t},e)}toSVG(e={}){return new sA().Is(this,e)}saveSVG(e={}){new sA().cs(this,e)}async saveCanvas(e,s="png",r={}){await new RA().Fs(this.Wt,{...r,filename:e,format:s})}},UA=Q=>class extends Q{async loadFont(e){return this._t.Ht(e).then(()=>{const s=this._t.maxGlyphDimensions;this.ne.qt(s.width,s.height),this.Os.ee()})}fontSize(e){if(!I.C(typeof e=="number"&&e>0,"Font size must be a positive number greater than 0.",{method:"fontSize",providedValue:e})||this._t.fontSize===e)return;this._t.Rt(e);const s=this._t.maxGlyphDimensions;this.ne.qt(s.width,s.height),this.Os.ee(),this.Dt.UA()}},YA=Q=>class extends Q{addConverter(e){return this.Os.add(e)}removeConverter(e){this.Os.remove(e)}};class SA{constructor(){n(this,"Dt");n(this,"_t");n(this,"Os");n(this,"Wt");n(this,"ne")}}class z extends function(s,...r){return r.reduce((i,B)=>B(i),s)}(SA,fA,FA,UA,YA){constructor(s=null,r={}){super();n(this,"re");n(this,"Us");n(this,"ie");n(this,"ks");n(this,"Vs");n(this,"Rs",null);n(this,"Hs",0);n(this,"zs");n(this,"Ls",!0);n(this,"Js",0);n(this,"js",0);n(this,"Ks",0);n(this,"Ws",[]);n(this,"Ns",10);n(this,"Zs",!1);n(this,"Xs",!1);n(this,"qs",()=>{});n(this,"Ar",()=>{});n(this,"tr");this.re=s,this.Xs=s===null,this.ks=r.renderMode??"auto",this.Vs=r.frameRate??60,this.zs=1e3/this.Vs}static async create(s=null,r={}){const i=new this(s,r),B=i.Xs?r:void 0;let E,o;i.Wt=new tA(i.re,i.Xs,B),i.Dt=new QA(i.Wt.ge()),i.Xs?(E=r.width||800,o=r.height||600):(E=i.Wt.width||800,o=i.Wt.height||600),i.Us=i.Dt.TA(E,o),i._t=new q(i.Dt,r.fontSize??16),await i._t.Ut(r.fontSource);const g=i._t.maxGlyphDimensions;return i.ne=new AA(i.Wt.canvas,g.width,g.height),i.Os=new eA(i.Dt,i._t,i.ne),i.er(),i.sr(),i}er(){this.tr=()=>{this.Xs?this.Ar():this.rr()},window.addEventListener("resize",this.tr),window.ResizeObserver&&this.re&&!this.Xs&&(this.ie=new ResizeObserver(()=>{this.rr()}),this.ie.observe(this.re))}render(){this.Br(),this.Ks++,this.Zs?console.warn("Cannot render: Required resources have been disposed"):(this.Xs?(this.Us.begin(),this.qs(),this.Us.end()):this.Us.update(this.re),this.Os.hasEnabledConverters()?(this.Os.Te(this.Us),this.Dt.SA(0),this.Dt.kA(this.Os.texture,this.ne.offsetX,this.ne.offsetY,this.Os.texture.width,this.Os.texture.height)):(this.Dt.OA(),this.Dt.kA(this.Us,this.ne.offsetX,this.ne.offsetY,this.Us.width,this.Us.height)))}rr(){this.Wt.ee(),this.Us.resize(this.Wt.width,this.Wt.height),this.ne.ee(),this.Os.ee(),this.Dt.UA(),this.ks!=="manual"&&this.render()}sr(){if(this.ks!=="auto"||!this.Ls)return;this.Hs=performance.now();const s=r=>{if(!this.Ls)return void(this.Rs=null);const i=r-this.Hs;i>=this.zs&&(this.render(),this.Hs=r-i%this.zs),this.Ls&&(this.Rs=requestAnimationFrame(s))};this.Rs=requestAnimationFrame(s)}Br(){const s=performance.now();if(this.js>0){const r=s-this.js;this.Ws.push(r),this.Ws.length>this.Ns&&this.Ws.shift();const i=this.Ws.reduce((B,E)=>B+E,0)/this.Ws.length;this.Js=1e3/i}this.js=s}ir(){this.Rs&&(cancelAnimationFrame(this.Rs),this.Rs=null)}renderMode(s){this.ks!==s&&(this.ir(),this.ks=s,s==="auto"&&this.Ls&&this.sr())}frameRate(s){if(s===void 0)return this.Js;this.Vs=s,this.zs=1e3/s,this.ks==="auto"&&this.Ls&&(this.ir(),this.sr())}noLoop(){this.Ls&&(this.Ls=!1,this.Rs&&(cancelAnimationFrame(this.Rs),this.Rs=null))}loop(){this.Ls||(this.Ls=!0,this.ks==="auto"&&this.sr())}redraw(s=1){if(I.C(typeof s=="number"&&s>0&&Number.isInteger(s),"Redraw count must be a positive integer.",{method:"redraw",providedValue:s}))for(let r=0;r<s;r++)this.render()}isLooping(){return this.ks==="auto"&&this.Ls}draw(s){this.qs=s}windowResized(s){this.Ar=s}resizeCanvas(s,r){this.Xs&&(this.Wt.ee(s,r),this.Us.resize(this.Wt.width,this.Wt.height),this.ne.ee(),this.Os.ee(),this.Dt.UA(),this.ks!=="manual"&&this.render())}destroy(){this.Zs||(this.ir(),window.removeEventListener("resize",this.tr),this.ie&&this.ie.disconnect(),this.Os.S(),this._t.S(),this.Us.S(),this.Dt.S(),this.Zs=!0)}get grid(){return this.ne}get font(){return this._t}get mode(){return this.ks}get pipeline(){return this.Os}get frameCount(){return this.Ks}set frameCount(s){this.Ks=s}get width(){return this.Wt.width}get height(){return this.Wt.height}get canvas(){return this.Wt}get isDisposed(){return this.Zs}}class Y{constructor(){throw new P("Textmode is a static class and cannot be instantiated.")}static async create(e,s={}){if(!(e==null||e instanceof HTMLCanvasElement||e instanceof HTMLVideoElement||typeof e=="object"))throw new P("First parameter must be HTMLCanvasElement, HTMLVideoElement, or options object.");if(typeof s!="object")throw new P("Second parameter must be an options object.");if(e instanceof HTMLCanvasElement||e instanceof HTMLVideoElement)return z.create(e,s);{const r=e||{};return z.create(null,r)}}static setErrorLevel(e){I.u(e)}static get version(){return"0.1.9-beta.2"}}const OA=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),WA=Y.create,LA=Y.setErrorLevel,kA=Y.version;d.TextmodeCanvas=tA,d.TextmodeConversionPipeline=eA,d.TextmodeErrorLevel=M,d.TextmodeFont=q,d.TextmodeGrid=AA,d.Textmodifier=z,d.converters=IA,d.create=WA,d.default=Y,d.export=OA,d.setErrorLevel=LA,d.textmode=Y,d.version=kA,Object.defineProperties(d,{Qr:{value:!0},[Symbol.toStringTag]:{value:"Module"}})},typeof exports=="object"&&typeof module<"u"?t(exports):typeof define=="function"&&define.amd?define(["exports"],t):t((A=typeof globalThis<"u"?globalThis:A||self).textmode={});
|
package/dist/textmode.umd.min.js
CHANGED
|
@@ -42,7 +42,7 @@ void main() {\r
|
|
|
42
42
|
\r
|
|
43
43
|
gl_Position = vec4(pos, 0.0, 1.0);\r
|
|
44
44
|
}\r
|
|
45
|
-
`,wt={enabled:!0,characters:" .:-=+*%@#",characterColor:[1,1,1,1],characterColorMode:"sampled",cellColor:[0,0,0,1],cellColorMode:"fixed",invert:!1,rotation:[0,0,0,255],flipHorizontally:!1,flipVertically:!1,brightnessRange:[0,255]};class W extends O{constructor(s,i,n){super(s,i,n,{...wt});c(this,"Rs");c(this,"Vs");c(this,"ks");c(this,"Is");c(this,"zs");c(this,"Es");this.Rs=new M(s.context,G,"precision lowp float;uniform sampler2D u_sketchTexture;uniform vec2 u_gridCellDimensions;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec2 cellCenter=(floor(v_uv*u_gridCellDimensions)+vec2(0.5))/u_gridCellDimensions;vec4 color=texture2D(u_sketchTexture,cellCenter);float brightness=dot(color.rgb,vec3(0.299,0.587,0.114));float brightnessValue=brightness*255.0;if(brightnessValue>=u_brightnessRange.x&&brightnessValue<=u_brightnessRange.y){gl_FragColor=color;}else{gl_FragColor=vec4(0.0);}}"),this.Vs=new M(s.context,G,"precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_fillColor;uniform bool u_useFixedColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){if(u_useFixedColor){gl_FragColor=u_fillColor;}else{gl_FragColor=sampleColor;}}else{gl_FragColor=vec4(0.0);}}"),this.Is=new M(s.context,G,"precision lowp float;uniform sampler2D u_sampleTexture;uniform bool u_invert;uniform bool u_flipHorizontally;uniform bool u_flipVertically;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){float invertValue=u_invert ? 1.0 : 0.0;float flipHValue=u_flipHorizontally ? 1.0 : 0.0;float flipVValue=u_flipVertically ? 1.0 : 0.0;gl_FragColor=vec4(invertValue,flipHValue,flipVValue,1.0);}else{gl_FragColor=vec4(0.0);}}"),this.zs=new M(s.context,G,"precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_rotationColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){gl_FragColor=u_rotationColor;}else{gl_FragColor=vec4(0.0);}}"),this.ks=new M(s.context,G,"precision lowp float;uniform sampler2D u_colorSampleFramebuffer;uniform sampler2D u_charPaletteTexture;uniform vec2 u_charPaletteSize;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec4 color=texture2D(u_colorSampleFramebuffer,v_uv);if(color.a==0.0){gl_FragColor=vec4(0.0);return;}float brightness=dot(color.rgb,vec3(0.299,0.587,0.114))*255.0;vec2 range=u_brightnessRange;if(brightness<range.x||brightness>range.y){gl_FragColor=vec4(0.0);return;}float t=(brightness-range.x)/(range.y-range.x);float idx=clamp(floor(t*u_charPaletteSize.x),0.0,u_charPaletteSize.x-1.0);vec3 charColor=texture2D(u_charPaletteTexture,vec2((idx+0.5)/u_charPaletteSize.x,0.0)).rgb;gl_FragColor=vec4(charColor,1.0);}"),this.Es=this.ve.Ut(this.ps.cols,this.ps.rows)}Gs(s){const i=this.ps.cols,n=this.ps.rows;this.Es.begin(),this.ve.jt(),this.ve.yt(this.Rs),this.ve.Et("u_sketchTexture",s),this.ve.Et("u_gridCellDimensions",[i,n]),this.ve.Et("u_brightnessRange",this.l.brightnessRange),this.ve.Gt(0,0,i,n),this.Es.end(),this._s.begin(),this.ve.jt(),this.ve.yt(this.Vs),this.ve.Et("u_sampleTexture",this.Es),this.ve.Et("u_fillColor",this.l.characterColor),this.ve.Et("u_useFixedColor",this.l.characterColorMode==="fixed"),this.ve.Gt(0,0,i,n),this._s.end(),this.vs.begin(),this.ve.jt(),this.ve.yt(this.Vs),this.ve.Et("u_sampleTexture",this.Es),this.ve.Et("u_fillColor",this.l.cellColor),this.ve.Et("u_useFixedColor",this.l.cellColorMode==="fixed"),this.ve.Gt(0,0,i,n),this.vs.end(),this.ws.begin(),this.ve.jt(),this.ve.yt(this.Is),this.ve.Et("u_sampleTexture",this.Es),this.ve.Et("u_invert",this.l.invert),this.ve.Et("u_flipHorizontally",this.l.flipHorizontally),this.ve.Et("u_flipVertically",this.l.flipVertically),this.ve.Gt(0,0,i,n),this.ws.end(),this.bs.begin(),this.ve.jt(),this.ve.yt(this.zs),this.ve.Et("u_sampleTexture",this.Es),this.ve.Et("u_rotationColor",this.l.rotation),this.ve.Gt(0,0,i,n),this.bs.end(),this.gs.begin(),this.ve.jt(),this.ve.yt(this.ks),this.ve.Et("u_colorSampleFramebuffer",this.Es),this.ve.Et("u_charPaletteTexture",this.Fs.texture),this.ve.Et("u_charPaletteSize",[this.Fs.colors.length,1]),this.ve.Et("u_brightnessRange",this.l.brightnessRange),this.ve.Gt(0,0,i,n),this.gs.end()}ss(){super.ss(),this.Es.resize(this.ps.cols,this.ps.rows)}brightnessRange(s){C.m(Array.isArray(s)&&s.length===2&&s.every(i=>typeof i=="number"&&i>=0&&i<=255),"Brightness range must be an array of two numbers between 0 and 255.",{method:"brightnessRange",providedValue:s})&&(this.l.brightnessRange=s)}}const Ct=Object.freeze(Object.defineProperty({__proto__:null,TextmodeBrightnessConverter:W,TextmodeConverter:S,TextmodeFeatureConverter:O},Symbol.toStringTag,{value:"Module"}));class rt{constructor(r,s,i){c(this,"ve");c(this,"Te");c(this,"ps");c(this,"Ps");c(this,"As");c(this,"Us");c(this,"Ls");c(this,"js");c(this,"gs");c(this,"_s");c(this,"vs");c(this,"bs");c(this,"ws");this.ve=r,this.Te=s,this.ps=i,this.js=this.ve.It(B,"precision mediump float;uniform sampler2D u_characterTexture;uniform vec2 u_charsetDimensions;uniform sampler2D u_primaryColorTexture;uniform sampler2D u_secondaryColorTexture;uniform sampler2D u_transformTexture;uniform sampler2D u_asciiCharacterTexture;uniform sampler2D u_rotationTexture;uniform sampler2D u_captureTexture;uniform vec2 u_captureDimensions;uniform int u_backgroundMode;uniform vec2 u_gridCellDimensions;uniform vec2 u_gridPixelDimensions;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){vec2 adjustedCoord=gl_FragCoord.xy/u_gridPixelDimensions;vec2 gridCoord=adjustedCoord*u_gridCellDimensions;vec2 cellCoord=floor(gridCoord);vec2 charIndexTexCoord=(cellCoord+0.5)/u_gridCellDimensions;vec4 primaryColor=texture2D(u_primaryColorTexture,charIndexTexCoord);vec4 secondaryColor=texture2D(u_secondaryColorTexture,charIndexTexCoord);vec4 transformColor=texture2D(u_transformTexture,charIndexTexCoord);bool isInverted=transformColor.r>0.5;bool flipHorizontal=transformColor.g>0.5;bool flipVertical=transformColor.b>0.5;vec4 encodedIndexVec=texture2D(u_asciiCharacterTexture,charIndexTexCoord);if(encodedIndexVec.a<0.01){gl_FragColor=(u_backgroundMode==0)? vec4(0.0):texture2D(u_captureTexture,gl_FragCoord.xy/u_captureDimensions);return;}int charIndex=int(encodedIndexVec.r*255.0+0.5)+int(encodedIndexVec.g*255.0+0.5)*256;int charCol=int(mod(float(charIndex),u_charsetDimensions.x));int charRow=charIndex/int(u_charsetDimensions.x);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/u_charsetDimensions;vec4 rotationColor=texture2D(u_rotationTexture,charIndexTexCoord);float scaledAngle=rotationColor.r*255.0+rotationColor.g;float rotationAngle=(scaledAngle*360.0/255.0)*0.017453292;vec2 fractionalPart=fract(gridCoord)-0.5;if(flipHorizontal)fractionalPart.x=-fractionalPart.x;if(flipVertical)fractionalPart.y=-fractionalPart.y;fractionalPart=rotate2D(rotationAngle)*fractionalPart+0.5;vec2 cellSize=1.0/u_charsetDimensions;vec2 texCoord=charCoord+fractionalPart*cellSize;vec2 cellMax=charCoord+cellSize;if(any(lessThan(texCoord,charCoord))||any(greaterThan(texCoord,cellMax))){gl_FragColor=isInverted ? primaryColor : secondaryColor;return;}vec4 charTexel=texture2D(u_characterTexture,texCoord);if(isInverted)charTexel.rgb=1.0-charTexel.rgb;gl_FragColor=mix(secondaryColor,primaryColor,charTexel);}"),this.As=new W(r,s,i),this.Us=new S(r,s,i),this.Ps=[this.As,this.Us],this.gs=this.ve.Ut(i.cols,i.rows),this._s=this.ve.Ut(i.cols,i.rows),this.vs=this.ve.Ut(i.cols,i.rows),this.bs=this.ve.Ut(i.cols,i.rows),this.ws=this.ve.Ut(i.cols,i.rows),this.Ls=this.ve.Ut(this.ps.width,this.ps.height)}Hs(r){for(const i of this.Ps)i.options.enabled&&i instanceof O&&i.Gs(r);const s=(i,n)=>{i.begin(),this.ve.jt();for(const o of this.Ps)o.options.enabled&&this.ve.Ot(n(o),0,0);i.end()};s(this.gs,i=>i.characterFramebuffer),s(this._s,i=>i.primaryColorFramebuffer),s(this.vs,i=>i.secondaryColorFramebuffer),s(this.bs,i=>i.rotationFramebuffer),s(this.ws,i=>i.transformFramebuffer),this.Ls.begin(),this.ve.jt(),this.ve.yt(this.js),this.ve.Et("u_characterTexture",this.Te.fontFramebuffer),this.ve.Et("u_charsetDimensions",[this.Te.textureColumns,this.Te.textureRows]),this.ve.Et("u_asciiCharacterTexture",this.gs.texture),this.ve.Et("u_primaryColorTexture",this._s.texture),this.ve.Et("u_secondaryColorTexture",this.vs.texture),this.ve.Et("u_transformTexture",this.ws.texture),this.ve.Et("u_rotationTexture",this.bs.texture),this.ve.Et("u_captureTexture",r.texture),this.ve.Et("u_backgroundMode",!1),this.ve.Et("u_captureDimensions",[r.width,r.height]),this.ve.Et("u_gridCellDimensions",[this.ps.cols,this.ps.rows]),this.ve.Et("u_gridPixelDimensions",[this.ps.width,this.ps.height]),this.ve.Gt(0,0,this.Ls.width,this.Ls.height),this.Ls.end()}add(r){if(!C.m(r==="brightness"||r==="custom",'Converter type must be either "brightness" or "custom".',{method:"add",providedValue:r}))return;let s;return s=r==="brightness"?new W(this.ve,this.Te,this.ps):new S(this.ve,this.Te,this.ps),this.Ps.push(s),s}remove(r){if(!C.m(r instanceof S,"Parameter must be a TextmodeConverter instance.",{method:"remove",providedValue:r}))return;const s=this.Ps.indexOf(r);C.m(s!==-1,"Converter instance not found in pipeline.",{method:"remove",providedValue:r,convertersCount:this.Ps.length})&&this.Ps.splice(s,1)}swap(r,s){const i=(a,u)=>{if(typeof a=="number")return C.m(Number.isInteger(a)&&a>=0&&a<this.Ps.length,u+" index must be a valid integer within the converter array bounds.",{method:"swap",providedValue:a,convertersCount:this.Ps.length})?a:null;if(a instanceof S){const d=this.Ps.indexOf(a);return C.m(d!==-1,u+" converter instance not found in pipeline.",{method:"swap",providedValue:a,convertersCount:this.Ps.length})?d:null}return C.m(!1,u+" parameter must be either an integer index or a TextmodeConverter instance.",{method:"swap",providedValue:a}),null},n=i(r,"First"),o=i(s,"Second");if(n===null||o===null||!C.m(n!==o,"Cannot swap a converter with itself.",{method:"swap",firstIndex:n,secondIndex:o}))return;const h=this.Ps[n];this.Ps[n]=this.Ps[o],this.Ps[o]=h}ss(){this.Ls.resize(this.ps.width,this.ps.height);const r=this.ps.cols,s=this.ps.rows;this.gs.resize(r,s),this._s.resize(r,s),this.vs.resize(r,s),this.bs.resize(r,s),this.ws.resize(r,s);for(const i of this.Ps)i.ss()}hasEnabledConverters(){return this.Ps.some(r=>r.options.enabled)}disable(){for(const r of this.Ps)r.disable()}enable(){for(const r of this.Ps)r.enable()}G(){for(const r of this.Ps)r.G();this.gs.G(),this._s.G(),this.vs.G(),this.bs.G(),this.ws.G(),this.Ls.G(),this.js.G()}get texture(){return this.Ls}get characterFramebuffer(){return this.gs}get primaryColorFramebuffer(){return this._s}get secondaryColorFramebuffer(){return this.vs}get rotationFramebuffer(){return this.bs}get transformFramebuffer(){return this.ws}get brightness(){return this.As}get custom(){return this.Us}}const yt=l=>class extends l{fill(r,s,i,n){this.ve.$t(r,s,i,n)}stroke(r,s,i,n){this.ve.Ft(r,s,i,n)}strokeWeight(r){this.ve.Tt(r)}noStroke(){this.ve.Mt()}noFill(){this.ve.St()}rotate(r){this.ve.Dt(r)}push(){this.ve.Rt()}pop(){this.ve.Vt()}rect(r,s,i=1,n=1){this.ve.Gt(r,s,i,n)}line(r,s,i,n){this.ve.At(r,s,i,n)}background(r,s=r,i=r,n=255){this.ve.Lt(r,s,i,n)}createShader(r,s){return this.ve.It(r,s)}createFilterShader(r){return this.ve.zt(r)}shader(r){this.ve.yt(r)}setUniform(r,s){this.ve.Et(r,s)}};class N{Os(r){const s=r.characterFramebuffer,i=r.primaryColorFramebuffer,n=r.secondaryColorFramebuffer,o=r.transformFramebuffer,h=r.rotationFramebuffer;return s==null||s.loadPixels(),i==null||i.loadPixels(),n==null||n.loadPixels(),o==null||o.loadPixels(),h==null||h.loadPixels(),{characterPixels:(s==null?void 0:s.pixels)||new Uint8Array(0),primaryColorPixels:(i==null?void 0:i.pixels)||new Uint8Array(0),secondaryColorPixels:(n==null?void 0:n.pixels)||new Uint8Array(0),transformPixels:(o==null?void 0:o.pixels)||new Uint8Array(0),rotationPixels:(h==null?void 0:h.pixels)||new Uint8Array(0)}}Bs(r,s){return r[s]+(r[s+1]<<8)}Ws(r,s){return{r:r[s],g:r[s+1],b:r[s+2],a:r[s+3]}}}class z{Ns(r,s){return new Blob([r],{type:s})}Xs(r,s,i){try{const n=this.Ns(r,i),o=URL.createObjectURL(n),h=document.createElement("a");h.href=o,h.download=s,h.style.display="none",h.rel="noopener",document.body.appendChild(h),h.click(),document.body.removeChild(h),URL.revokeObjectURL(o)}catch(n){throw console.error("Failed to download file:",n),Error("File download failed: "+(n instanceof Error?n.message:"Unknown error"))}}qs(){return new Date().toISOString().slice(0,19).replace(/:/g,"-")}Ys(){const r=new Date;return{date:r.toISOString().split("T")[0],time:r.toTimeString().split(" ")[0].replace(/:/g,"-")}}Qs(r){return r.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)}Zs(){return"'textmode-export'-"+this.qs()}}class _t extends N{Js(r,s,i){const n=r[i]===255,o=r[i+1]===255,h=r[i+2]===255,a=s[i],u=s[i+1];return{isInverted:n,flipHorizontal:o,flipVertical:h,rotation:Math.round(360*(a+u/255)/255*100)/100}}Ks(r,s,i){return{x:r,y:s,cellX:r*i.cellWidth,cellY:s*i.cellHeight}}tr(r,s){const i=[];let n=0;for(let o=0;o<s.rows;o++)for(let h=0;h<s.cols;h++){const a=4*n,u=this.Bs(r.characterPixels,a);let d=this.Ws(r.primaryColorPixels,a),f=this.Ws(r.secondaryColorPixels,a);const p=this.Js(r.transformPixels,r.rotationPixels,a);if(p.isInverted){const x=d;d=f,f=x}const g=this.Ks(h,o,s);i.push({charIndex:u,primaryColor:d,secondaryColor:f,transform:p,position:g}),n++}return i}}class Tt{er(r,s){const i=r.cmap;for(const n of i.tables)if(n.format===4){for(let o=0;o<n.startCount.length;o++)if(s>=n.startCount[o]&&s<=n.endCount[o]){if(n.idRangeOffset[o]===0)return s+n.idDelta[o]&65535;{const h=n.idRangeOffset[o]/2+(s-n.startCount[o])-(n.startCount.length-o);if(h>=0&&h<n.glyphIdArray.length){const a=n.glyphIdArray[h];if(a!==0)return a+n.idDelta[o]&65535}}}}return 0}sr(r,s,i,n,o){const h=o/r.head.unitsPerEm;return{getBoundingBox:()=>({x1:i+s.xMin*h,y1:n+-s.yMax*h,x2:i+s.xMax*h,y2:n+-s.yMin*h}),toSVG:()=>this.rr(s,i,n,h)}}rr(r,s,i,n){if(!r||!r.xs)return"";const{xs:o,ys:h,endPts:a,flags:u}=r;if(!(o&&h&&a&&u))return"";let d="",f=0;for(let p=0;p<a.length;p++){const g=a[p];if(!(g<f)){if(g>=f){const x=s+o[f]*n,v=i-h[f]*n;d+=`M${x.toFixed(2)},${v.toFixed(2)}`;let m=f+1;for(;m<=g;)if(1&u[m]){const T=s+o[m]*n,y=i-h[m]*n;d+=`L${T.toFixed(2)},${y.toFixed(2)}`,m++}else{const T=s+o[m]*n,y=i-h[m]*n;let _=m+1>g?f:m+1;if(1&u[_]){const F=s+o[_]*n,A=i-h[_]*n;d+=`Q${T.toFixed(2)},${y.toFixed(2)} ${F.toFixed(2)},${A.toFixed(2)}`,m=_+1}else{const F=(T+(s+o[_]*n))/2,A=(y+(i-h[_]*n))/2;d+=`Q${T.toFixed(2)},${y.toFixed(2)} ${F.toFixed(2)},${A.toFixed(2)}`,m=_}}d+="Z"}f=g+1}}return d}ir(r,s,i,n,o){const h=r.codePointAt(0)||0,a=this.er(s,h);let u=null;return s.glyf&&s.glyf[a]!==null?u=s.glyf[a]:R&&R.T&&R.T.glyf&&R.T.glyf.Bt&&(u=R.T.glyf.Bt(s,a),s.glyf&&u&&(s.glyf[a]=u)),this.sr(s,u,i,n,o)}nr(r,s,i,n,o,h,a,u){const d=i+(o-u*(a/s.head.unitsPerEm))/2,f=n+(h+.7*a)/2;return this.ir(r,s,d,f,a).toSVG()||null}}class Et{constructor(){c(this,"ar");this.ar=new Tt}hr(r){return`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
45
|
+
`,wt={enabled:!0,characters:" .:-=+*%@#",characterColor:[1,1,1,1],characterColorMode:"sampled",cellColor:[0,0,0,1],cellColorMode:"fixed",invert:!1,rotation:[0,0,0,255],flipHorizontally:!1,flipVertically:!1,brightnessRange:[0,255]};class W extends O{constructor(s,i,n){super(s,i,n,{...wt});c(this,"Rs");c(this,"Vs");c(this,"ks");c(this,"Is");c(this,"zs");c(this,"Es");this.Rs=new M(s.context,G,"precision lowp float;uniform sampler2D u_sketchTexture;uniform vec2 u_gridCellDimensions;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec2 cellCenter=(floor(v_uv*u_gridCellDimensions)+vec2(0.5))/u_gridCellDimensions;vec4 color=texture2D(u_sketchTexture,cellCenter);float brightness=dot(color.rgb,vec3(0.299,0.587,0.114));float brightnessValue=brightness*255.0;if(brightnessValue>=u_brightnessRange.x&&brightnessValue<=u_brightnessRange.y){gl_FragColor=color;}else{gl_FragColor=vec4(0.0);}}"),this.Vs=new M(s.context,G,"precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_fillColor;uniform bool u_useFixedColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){if(u_useFixedColor){gl_FragColor=u_fillColor;}else{gl_FragColor=sampleColor;}}else{gl_FragColor=vec4(0.0);}}"),this.Is=new M(s.context,G,"precision lowp float;uniform sampler2D u_sampleTexture;uniform bool u_invert;uniform bool u_flipHorizontally;uniform bool u_flipVertically;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){float invertValue=u_invert ? 1.0 : 0.0;float flipHValue=u_flipHorizontally ? 1.0 : 0.0;float flipVValue=u_flipVertically ? 1.0 : 0.0;gl_FragColor=vec4(invertValue,flipHValue,flipVValue,1.0);}else{gl_FragColor=vec4(0.0);}}"),this.zs=new M(s.context,G,"precision lowp float;uniform sampler2D u_sampleTexture;uniform vec4 u_rotationColor;varying vec2 v_uv;void main(){vec4 sampleColor=texture2D(u_sampleTexture,v_uv);if(sampleColor.a>0.0){gl_FragColor=u_rotationColor;}else{gl_FragColor=vec4(0.0);}}"),this.ks=new M(s.context,G,"precision lowp float;uniform sampler2D u_colorSampleFramebuffer;uniform sampler2D u_charPaletteTexture;uniform vec2 u_charPaletteSize;uniform vec2 u_brightnessRange;varying vec2 v_uv;void main(){vec4 color=texture2D(u_colorSampleFramebuffer,v_uv);if(color.a==0.0){gl_FragColor=vec4(0.0);return;}float brightness=dot(color.rgb,vec3(0.299,0.587,0.114))*255.0;vec2 range=u_brightnessRange;if(brightness<range.x||brightness>range.y){gl_FragColor=vec4(0.0);return;}float t=(brightness-range.x)/(range.y-range.x);float idx=clamp(floor(t*u_charPaletteSize.x),0.0,u_charPaletteSize.x-1.0);vec3 charColor=texture2D(u_charPaletteTexture,vec2((idx+0.5)/u_charPaletteSize.x,0.0)).rgb;gl_FragColor=vec4(charColor,1.0);}"),this.Es=this.ve.Ut(this.ps.cols,this.ps.rows)}Gs(s){const i=this.ps.cols,n=this.ps.rows;this.Es.begin(),this.ve.jt(),this.ve.yt(this.Rs),this.ve.Et("u_sketchTexture",s),this.ve.Et("u_gridCellDimensions",[i,n]),this.ve.Et("u_brightnessRange",this.l.brightnessRange),this.ve.Gt(0,0,i,n),this.Es.end(),this._s.begin(),this.ve.jt(),this.ve.yt(this.Vs),this.ve.Et("u_sampleTexture",this.Es),this.ve.Et("u_fillColor",this.l.characterColor),this.ve.Et("u_useFixedColor",this.l.characterColorMode==="fixed"),this.ve.Gt(0,0,i,n),this._s.end(),this.vs.begin(),this.ve.jt(),this.ve.yt(this.Vs),this.ve.Et("u_sampleTexture",this.Es),this.ve.Et("u_fillColor",this.l.cellColor),this.ve.Et("u_useFixedColor",this.l.cellColorMode==="fixed"),this.ve.Gt(0,0,i,n),this.vs.end(),this.ws.begin(),this.ve.jt(),this.ve.yt(this.Is),this.ve.Et("u_sampleTexture",this.Es),this.ve.Et("u_invert",this.l.invert),this.ve.Et("u_flipHorizontally",this.l.flipHorizontally),this.ve.Et("u_flipVertically",this.l.flipVertically),this.ve.Gt(0,0,i,n),this.ws.end(),this.bs.begin(),this.ve.jt(),this.ve.yt(this.zs),this.ve.Et("u_sampleTexture",this.Es),this.ve.Et("u_rotationColor",this.l.rotation),this.ve.Gt(0,0,i,n),this.bs.end(),this.gs.begin(),this.ve.jt(),this.ve.yt(this.ks),this.ve.Et("u_colorSampleFramebuffer",this.Es),this.ve.Et("u_charPaletteTexture",this.Fs.texture),this.ve.Et("u_charPaletteSize",[this.Fs.colors.length,1]),this.ve.Et("u_brightnessRange",this.l.brightnessRange),this.ve.Gt(0,0,i,n),this.gs.end()}ss(){super.ss(),this.Es.resize(this.ps.cols,this.ps.rows)}brightnessRange(s){C.m(Array.isArray(s)&&s.length===2&&s.every(i=>typeof i=="number"&&i>=0&&i<=255),"Brightness range must be an array of two numbers between 0 and 255.",{method:"brightnessRange",providedValue:s})&&(this.l.brightnessRange=s)}}const Ct=Object.freeze(Object.defineProperty({__proto__:null,TextmodeBrightnessConverter:W,TextmodeConverter:S,TextmodeFeatureConverter:O},Symbol.toStringTag,{value:"Module"}));class rt{constructor(r,s,i){c(this,"ve");c(this,"Te");c(this,"ps");c(this,"Ps");c(this,"As");c(this,"Us");c(this,"Ls");c(this,"js");c(this,"gs");c(this,"_s");c(this,"vs");c(this,"bs");c(this,"ws");this.ve=r,this.Te=s,this.ps=i,this.js=this.ve.It(B,"precision mediump float;uniform sampler2D u_characterTexture;uniform vec2 u_charsetDimensions;uniform sampler2D u_primaryColorTexture;uniform sampler2D u_secondaryColorTexture;uniform sampler2D u_transformTexture;uniform sampler2D u_asciiCharacterTexture;uniform sampler2D u_rotationTexture;uniform sampler2D u_captureTexture;uniform vec2 u_captureDimensions;uniform int u_backgroundMode;uniform vec2 u_gridCellDimensions;uniform vec2 u_gridPixelDimensions;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){vec2 adjustedCoord=gl_FragCoord.xy/u_gridPixelDimensions;vec2 gridCoord=adjustedCoord*u_gridCellDimensions;vec2 cellCoord=floor(gridCoord);vec2 charIndexTexCoord=(cellCoord+0.5)/u_gridCellDimensions;vec4 primaryColor=texture2D(u_primaryColorTexture,charIndexTexCoord);vec4 secondaryColor=texture2D(u_secondaryColorTexture,charIndexTexCoord);vec4 transformColor=texture2D(u_transformTexture,charIndexTexCoord);bool isInverted=transformColor.r>0.5;bool flipHorizontal=transformColor.g>0.5;bool flipVertical=transformColor.b>0.5;vec4 encodedIndexVec=texture2D(u_asciiCharacterTexture,charIndexTexCoord);if(encodedIndexVec.a<0.01){gl_FragColor=(u_backgroundMode==0)? vec4(0.0):texture2D(u_captureTexture,gl_FragCoord.xy/u_captureDimensions);return;}int charIndex=int(encodedIndexVec.r*255.0+0.5)+int(encodedIndexVec.g*255.0+0.5)*256;int charCol=int(mod(float(charIndex),u_charsetDimensions.x));int charRow=charIndex/int(u_charsetDimensions.x);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/u_charsetDimensions;vec4 rotationColor=texture2D(u_rotationTexture,charIndexTexCoord);float scaledAngle=rotationColor.r*255.0+rotationColor.g;float rotationAngle=(scaledAngle*360.0/255.0)*0.017453292;vec2 fractionalPart=fract(gridCoord)-0.5;if(flipHorizontal)fractionalPart.x=-fractionalPart.x;if(flipVertical)fractionalPart.y=-fractionalPart.y;fractionalPart=rotate2D(rotationAngle)*fractionalPart+0.5;vec2 cellSize=1.0/u_charsetDimensions;vec2 texCoord=charCoord+fractionalPart*cellSize;vec2 cellMax=charCoord+cellSize;if(any(lessThan(texCoord,charCoord))||any(greaterThan(texCoord,cellMax))){gl_FragColor=isInverted ? primaryColor : secondaryColor;return;}vec4 charTexel=texture2D(u_characterTexture,texCoord);if(isInverted)charTexel.rgb=1.0-charTexel.rgb;gl_FragColor=mix(secondaryColor,primaryColor,charTexel);}"),this.As=new W(r,s,i),this.Us=new S(r,s,i),this.Ps=[this.As,this.Us],this.gs=this.ve.Ut(i.cols,i.rows),this._s=this.ve.Ut(i.cols,i.rows),this.vs=this.ve.Ut(i.cols,i.rows),this.bs=this.ve.Ut(i.cols,i.rows),this.ws=this.ve.Ut(i.cols,i.rows),this.Ls=this.ve.Ut(this.ps.width,this.ps.height)}Hs(r){for(const i of this.Ps)i.options.enabled&&i instanceof O&&i.Gs(r);const s=(i,n)=>{i.begin(),this.ve.jt();for(const o of this.Ps)o.options.enabled&&this.ve.Ot(n(o),0,0);i.end()};s(this.gs,i=>i.characterFramebuffer),s(this._s,i=>i.primaryColorFramebuffer),s(this.vs,i=>i.secondaryColorFramebuffer),s(this.bs,i=>i.rotationFramebuffer),s(this.ws,i=>i.transformFramebuffer),this.Ls.begin(),this.ve.jt(),this.ve.yt(this.js),this.ve.Et("u_characterTexture",this.Te.fontFramebuffer),this.ve.Et("u_charsetDimensions",[this.Te.textureColumns,this.Te.textureRows]),this.ve.Et("u_asciiCharacterTexture",this.gs.texture),this.ve.Et("u_primaryColorTexture",this._s.texture),this.ve.Et("u_secondaryColorTexture",this.vs.texture),this.ve.Et("u_transformTexture",this.ws.texture),this.ve.Et("u_rotationTexture",this.bs.texture),this.ve.Et("u_captureTexture",r.texture),this.ve.Et("u_backgroundMode",!1),this.ve.Et("u_captureDimensions",[r.width,r.height]),this.ve.Et("u_gridCellDimensions",[this.ps.cols,this.ps.rows]),this.ve.Et("u_gridPixelDimensions",[this.ps.width,this.ps.height]),this.ve.Gt(0,0,this.Ls.width,this.Ls.height),this.Ls.end()}add(r){if(!C.m(r==="brightness"||r==="custom",'Converter type must be either "brightness" or "custom".',{method:"add",providedValue:r}))return;let s;return s=r==="brightness"?new W(this.ve,this.Te,this.ps):new S(this.ve,this.Te,this.ps),this.Ps.push(s),s}remove(r){if(!C.m(r instanceof S,"Parameter must be a TextmodeConverter instance.",{method:"remove",providedValue:r}))return;const s=this.Ps.indexOf(r);C.m(s!==-1,"Converter instance not found in pipeline.",{method:"remove",providedValue:r,convertersCount:this.Ps.length})&&this.Ps.splice(s,1)}swap(r,s){const i=(a,u)=>{if(typeof a=="number")return C.m(Number.isInteger(a)&&a>=0&&a<this.Ps.length,u+" index must be a valid integer within the converter array bounds.",{method:"swap",providedValue:a,convertersCount:this.Ps.length})?a:null;if(a instanceof S){const d=this.Ps.indexOf(a);return C.m(d!==-1,u+" converter instance not found in pipeline.",{method:"swap",providedValue:a,convertersCount:this.Ps.length})?d:null}return C.m(!1,u+" parameter must be either an integer index or a TextmodeConverter instance.",{method:"swap",providedValue:a}),null},n=i(r,"First"),o=i(s,"Second");if(n===null||o===null||!C.m(n!==o,"Cannot swap a converter with itself.",{method:"swap",firstIndex:n,secondIndex:o}))return;const h=this.Ps[n];this.Ps[n]=this.Ps[o],this.Ps[o]=h}ss(){this.Ls.resize(this.ps.width,this.ps.height);const r=this.ps.cols,s=this.ps.rows;this.gs.resize(r,s),this._s.resize(r,s),this.vs.resize(r,s),this.bs.resize(r,s),this.ws.resize(r,s);for(const i of this.Ps)i.ss()}hasEnabledConverters(){return this.Ps.some(r=>r.options.enabled)}disable(){for(const r of this.Ps)r.disable()}enable(){for(const r of this.Ps)r.enable()}G(){for(const r of this.Ps)r.G();this.gs.G(),this._s.G(),this.vs.G(),this.bs.G(),this.ws.G(),this.Ls.G(),this.js.G()}get texture(){return this.Ls}get characterFramebuffer(){return this.gs}get primaryColorFramebuffer(){return this._s}get secondaryColorFramebuffer(){return this.vs}get rotationFramebuffer(){return this.bs}get transformFramebuffer(){return this.ws}get brightness(){return this.As}get custom(){return this.Us}}const yt=l=>class extends l{fill(r,s,i,n){this.ve.$t(r,s,i,n)}stroke(r,s,i,n){this.ve.Ft(r,s,i,n)}strokeWeight(r){this.ve.Tt(r)}noStroke(){this.ve.Mt()}noFill(){this.ve.St()}rotate(r){this.ve.Dt(r)}push(){this.ve.Rt()}pop(){this.ve.Vt()}rect(r,s,i=1,n=1){this.ve.Gt(r,s,i,n)}line(r,s,i,n){this.ve.At(r,s,i,n)}background(r,s=r,i=r,n=255){this.ve.Lt(r,s,i,n)}createShader(r,s){return this.ve.It(r,s)}createFilterShader(r){return this.ve.zt(r)}shader(r){this.ve.yt(r)}setUniform(r,s){this.ve.Et(r,s)}image(r,s,i,n,o){this.ve.Ot(r,s,i,n,o)}clear(){this.ve.jt()}createFramebuffer(r,s,i={}){return this.ve.Ut(r,s,i)}};class N{Os(r){const s=r.characterFramebuffer,i=r.primaryColorFramebuffer,n=r.secondaryColorFramebuffer,o=r.transformFramebuffer,h=r.rotationFramebuffer;return s==null||s.loadPixels(),i==null||i.loadPixels(),n==null||n.loadPixels(),o==null||o.loadPixels(),h==null||h.loadPixels(),{characterPixels:(s==null?void 0:s.pixels)||new Uint8Array(0),primaryColorPixels:(i==null?void 0:i.pixels)||new Uint8Array(0),secondaryColorPixels:(n==null?void 0:n.pixels)||new Uint8Array(0),transformPixels:(o==null?void 0:o.pixels)||new Uint8Array(0),rotationPixels:(h==null?void 0:h.pixels)||new Uint8Array(0)}}Bs(r,s){return r[s]+(r[s+1]<<8)}Ws(r,s){return{r:r[s],g:r[s+1],b:r[s+2],a:r[s+3]}}}class z{Ns(r,s){return new Blob([r],{type:s})}Xs(r,s,i){try{const n=this.Ns(r,i),o=URL.createObjectURL(n),h=document.createElement("a");h.href=o,h.download=s,h.style.display="none",h.rel="noopener",document.body.appendChild(h),h.click(),document.body.removeChild(h),URL.revokeObjectURL(o)}catch(n){throw console.error("Failed to download file:",n),Error("File download failed: "+(n instanceof Error?n.message:"Unknown error"))}}qs(){return new Date().toISOString().slice(0,19).replace(/:/g,"-")}Ys(){const r=new Date;return{date:r.toISOString().split("T")[0],time:r.toTimeString().split(" ")[0].replace(/:/g,"-")}}Qs(r){return r.replace(/[<>:"/\\|?*]/g,"_").replace(/\s+/g,"_").replace(/_{2,}/g,"_").replace(/^_+|_+$/g,"").substring(0,255)}Zs(){return"'textmode-export'-"+this.qs()}}class _t extends N{Js(r,s,i){const n=r[i]===255,o=r[i+1]===255,h=r[i+2]===255,a=s[i],u=s[i+1];return{isInverted:n,flipHorizontal:o,flipVertical:h,rotation:Math.round(360*(a+u/255)/255*100)/100}}Ks(r,s,i){return{x:r,y:s,cellX:r*i.cellWidth,cellY:s*i.cellHeight}}tr(r,s){const i=[];let n=0;for(let o=0;o<s.rows;o++)for(let h=0;h<s.cols;h++){const a=4*n,u=this.Bs(r.characterPixels,a);let d=this.Ws(r.primaryColorPixels,a),f=this.Ws(r.secondaryColorPixels,a);const p=this.Js(r.transformPixels,r.rotationPixels,a);if(p.isInverted){const x=d;d=f,f=x}const g=this.Ks(h,o,s);i.push({charIndex:u,primaryColor:d,secondaryColor:f,transform:p,position:g}),n++}return i}}class Tt{er(r,s){const i=r.cmap;for(const n of i.tables)if(n.format===4){for(let o=0;o<n.startCount.length;o++)if(s>=n.startCount[o]&&s<=n.endCount[o]){if(n.idRangeOffset[o]===0)return s+n.idDelta[o]&65535;{const h=n.idRangeOffset[o]/2+(s-n.startCount[o])-(n.startCount.length-o);if(h>=0&&h<n.glyphIdArray.length){const a=n.glyphIdArray[h];if(a!==0)return a+n.idDelta[o]&65535}}}}return 0}sr(r,s,i,n,o){const h=o/r.head.unitsPerEm;return{getBoundingBox:()=>({x1:i+s.xMin*h,y1:n+-s.yMax*h,x2:i+s.xMax*h,y2:n+-s.yMin*h}),toSVG:()=>this.rr(s,i,n,h)}}rr(r,s,i,n){if(!r||!r.xs)return"";const{xs:o,ys:h,endPts:a,flags:u}=r;if(!(o&&h&&a&&u))return"";let d="",f=0;for(let p=0;p<a.length;p++){const g=a[p];if(!(g<f)){if(g>=f){const x=s+o[f]*n,v=i-h[f]*n;d+=`M${x.toFixed(2)},${v.toFixed(2)}`;let m=f+1;for(;m<=g;)if(1&u[m]){const T=s+o[m]*n,y=i-h[m]*n;d+=`L${T.toFixed(2)},${y.toFixed(2)}`,m++}else{const T=s+o[m]*n,y=i-h[m]*n;let _=m+1>g?f:m+1;if(1&u[_]){const F=s+o[_]*n,A=i-h[_]*n;d+=`Q${T.toFixed(2)},${y.toFixed(2)} ${F.toFixed(2)},${A.toFixed(2)}`,m=_+1}else{const F=(T+(s+o[_]*n))/2,A=(y+(i-h[_]*n))/2;d+=`Q${T.toFixed(2)},${y.toFixed(2)} ${F.toFixed(2)},${A.toFixed(2)}`,m=_}}d+="Z"}f=g+1}}return d}ir(r,s,i,n,o){const h=r.codePointAt(0)||0,a=this.er(s,h);let u=null;return s.glyf&&s.glyf[a]!==null?u=s.glyf[a]:R&&R.T&&R.T.glyf&&R.T.glyf.Bt&&(u=R.T.glyf.Bt(s,a),s.glyf&&u&&(s.glyf[a]=u)),this.sr(s,u,i,n,o)}nr(r,s,i,n,o,h,a,u){const d=i+(o-u*(a/s.head.unitsPerEm))/2,f=n+(h+.7*a)/2;return this.ir(r,s,d,f,a).toSVG()||null}}class Et{constructor(){c(this,"ar");this.ar=new Tt}hr(r){return`<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
46
46
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
|
47
47
|
<svg width="${r.width}" height="${r.height}" viewBox="0 0 ${r.width} ${r.height}"
|
|
48
48
|
xmlns="http://www.w3.org/2000/svg" version="1.1">
|
|
@@ -60,4 +60,4 @@ void main() {\r
|
|
|
60
60
|
<g id="ascii-cells">`;for(const h of r)o+=this.mr(h,s,i,n);return o+=this.lr(),o}_r(r){return r.replace(/<path[^>]*d=""[^>]*\/>/g,"").replace(/\n\s*\n/g,`
|
|
61
61
|
`).replace(/[ \t]+$/gm,"")}}class Rt extends z{vr(r){return this.Ns(r,"image/svg+xml;charset=utf-8")}br(r,s){this.Xs(r,this.Qs(s)+".svg","image/svg+xml;charset=utf-8")}wr(r,s){this.br(r,s||this.Zs())}}class st{constructor(){c(this,"Cr");c(this,"yr");c(this,"$r");this.Cr=new _t,this.yr=new Et,this.$r=new Rt}Fr(r){return{includeBackgroundRectangles:r.includeBackgroundRectangles??!0,drawMode:r.drawMode??"fill",strokeWidth:r.strokeWidth??1,backgroundColor:r.backgroundColor??[0,0,0,0]}}Tr(r,s={}){const i=this.Fr(s),n=this.Cr.Os(r.pipeline),o=this.Cr.tr(n,r.grid),h=this.yr.gr(o,r.grid,r.font,i);return this.yr._r(h)}wr(r,s={}){const i=this.Tr(r,s),n=s.filename||this.$r.Zs();this.$r.wr(i,n)}}class Ft extends N{Mr(r,s,i,n=" "){var a;const o=[];let h=0;for(let u=0;u<s.rows;u++){const d=[];for(let f=0;f<s.cols;f++){const p=4*h,g=this.Bs(r.characterPixels,p),x=((a=i.characters[g])==null?void 0:a.character)||n;d.push(x),h++}o.push(d)}return o}}class Mt{Sr(r,s){const i=[];for(const o of r){let h=o.join("");s.preserveTrailingSpaces||(h=h.replace(/\s+$/,"")),i.push(h)}const n=s.lineEnding==="crlf"?`\r
|
|
62
62
|
`:`
|
|
63
|
-
`;return i.join(n)}}class At extends z{Dr(r,s){const i=this.Rr(s);this.Xs(r,i,"text/plain;charset=utf-8")}Rr(r){let s=this.Qs(r);return s===".txt"||s.length<=4?this.Zs():s}}class it{constructor(){c(this,"Cr");c(this,"yr");c(this,"$r");this.Cr=new Ft,this.yr=new Mt,this.$r=new At}Fr(r){return{preserveTrailingSpaces:r.preserveTrailingSpaces??!1,lineEnding:r.lineEnding??"lf",emptyCharacter:r.emptyCharacter??" "}}Vr(r,s={}){const i=this.Fr(s),n=this.Cr.Os(r.pipeline),o=this.Cr.Mr(n,r.grid,r.font,i.emptyCharacter);return this.yr.Sr(o,i)}Dr(r,s={}){const i=this.Vr(r,s),n=s.filename||this.$r.Zs();this.$r.Dr(i,n)}}class Pt extends N{kr(r,s=1,i="transparent"){const n=r.canvas;if(s===1&&i==="transparent")return n;const o=document.createElement("canvas"),h=o.getContext("2d"),a=Math.round(n.width*s),u=Math.round(n.height*s);return o.width=a,o.height=u,i!=="transparent"&&(h.fillStyle=i,h.fillRect(0,0,a,u)),h.imageSmoothingEnabled=!1,h.drawImage(n,0,0,n.width,n.height,0,0,a,u),o}}class Ut{Ir(r,s){const i=this.zr(s.format);return s.format==="png"?r.toDataURL(i):r.toDataURL(i,s.quality)}async Er(r,s){return new Promise((i,n)=>{const o=this.zr(s.format),h=a=>{a?i(a):n(Error(`Failed to generate ${s.format.toUpperCase()} blob`))};s.format==="png"?r.toBlob(h,o):r.toBlob(h,o,s.quality)})}zr(r){switch(r){case"png":return"image/png";case"jpg":return"image/jpeg";case"webp":return"image/webp";default:throw Error("Unsupported image format: "+r)}}}const Dt={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},nt={png:".png",jpg:".jpg",webp:".webp"};class St extends z{Gr(r,s,i){this.Pr(r,this.Qs(s)+nt[i])}Pr(r,s){const i=URL.createObjectURL(r);try{const n=document.createElement("a");n.href=i,n.download=s,n.style.display="none",n.rel="noopener",document.body.appendChild(n),n.click(),document.body.removeChild(n)}finally{URL.revokeObjectURL(i)}}Ar(r){return r in Dt&&r in nt}}class $t{constructor(){c(this,"Cr");c(this,"yr");c(this,"$r");this.Cr=new Pt,this.yr=new Ut,this.$r=new St}Fr(r){return{format:r.format??"png",quality:r.quality??1,scale:r.scale??1,backgroundColor:r.backgroundColor??"transparent"}}Ur(r){if(console.log("Validating image export options:",r),!this.$r.Ar(r.format))throw Error(`Saving '${r.format}' files is not supported`);if(r.quality<0||r.quality>1)throw Error("Image quality must be between 0.0 and 1.0");if(r.scale<=0)throw Error("Scale factor must be greater than 0");r.scale>10&&console.warn("Large scale factors may result in very large files and slow performance"),r.format==="jpg"&&r.backgroundColor==="transparent"&&(r.backgroundColor="black")}Lr(r,s={}){const i=this.Fr(s);if(this.Ur(i),i.scale===1&&i.backgroundColor==="transparent")return this.yr.Ir(r.canvas,i);const n=this.Cr.kr(r,i.scale,i.backgroundColor);return this.yr.Ir(n,i)}async Er(r,s={}){const i=this.Fr(s);if(this.Ur(i),i.scale===1&&i.backgroundColor==="transparent")return await this.yr.Er(r.canvas,i);const n=this.Cr.kr(r,i.scale,i.backgroundColor);return await this.yr.Er(n,i)}async Gr(r,s={}){const i=await this.Er(r,s),n=s.format??"png",o=s.filename||this.$r.Zs();this.$r.Gr(i,o,n)}}const It=l=>class extends l{toString(r={}){return new it().Vr({pipeline:this.jr,grid:this.ps,font:this.Te},r)}saveStrings(r={}){new it().Dr({pipeline:this.jr,grid:this.ps,font:this.Te},r)}toSVG(r={}){return new st().Tr(this,r)}saveSVG(r={}){new st().wr(this,r)}async saveCanvas(r,s="png",i={}){await new $t().Gr(this.Ye,{...i,filename:r,format:s})}},Gt=l=>class extends l{async loadFont(r){return this.Te.Oe(r).then(()=>{const s=this.Te.maxGlyphDimensions;this.ps.Ke(s.width,s.height),this.jr.ss()})}fontSize(r){if(!C.m(typeof r=="number"&&r>0,"Font size must be a positive number greater than 0.",{method:"fontSize",providedValue:r})||this.Te.fontSize===r)return;this.Te.He(r);const s=this.Te.maxGlyphDimensions;this.ps.Ke(s.width,s.height),this.jr.ss(),this.ve.Ht()}},kt=l=>class extends l{addConverter(r){return this.jr.add(r)}removeConverter(r){this.jr.remove(r)}};class Lt{constructor(){c(this,"ve");c(this,"Te");c(this,"jr");c(this,"Ye");c(this,"ps")}}class H extends function(s,...i){return i.reduce((n,o)=>o(n),s)}(Lt,yt,It,Gt,kt){constructor(s=null,i={}){super();c(this,"ns");c(this,"Hr");c(this,"ls");c(this,"Or");c(this,"Br");c(this,"Wr",null);c(this,"Nr",0);c(this,"Xr");c(this,"qr",!0);c(this,"Yr",0);c(this,"Qr",0);c(this,"Zr",0);c(this,"Jr",[]);c(this,"Kr",10);c(this,"ti",!1);c(this,"ei",!1);c(this,"si",()=>{});c(this,"ri",()=>{});c(this,"ii");this.ns=s,this.ei=s===null,this.Or=i.renderMode??"auto",this.Br=i.frameRate??60,this.Xr=1e3/this.Br}static async create(s=null,i={}){const n=new this(s,i),o=n.ei?i:void 0;let h,a;n.Ye=new et(n.ns,n.ei,o),n.ve=new lt(n.Ye.fs()),n.ei?(h=i.width||800,a=i.height||600):(h=n.Ye.width||800,a=n.Ye.height||600),n.Hr=n.ve.Ut(h,a),n.Te=new K(n.ve,i.fontSize??16),await n.Te.Ue(i.fontSource);const u=n.Te.maxGlyphDimensions;return n.ps=new tt(n.Ye.canvas,u.width,u.height),n.jr=new rt(n.ve,n.Te,n.ps),n.ni(),n.oi(),n}ni(){this.ii=()=>{this.ei?this.ri():this.ai()},window.addEventListener("resize",this.ii),window.ResizeObserver&&this.ns&&!this.ei&&(this.ls=new ResizeObserver(()=>{this.ai()}),this.ls.observe(this.ns))}render(){this.hi(),this.Zr++,this.ti?console.warn("Cannot render: Required resources have been disposed"):(this.ei?(this.Hr.begin(),this.si(),this.Hr.end()):this.Hr.update(this.ns),this.jr.hasEnabledConverters()?(this.jr.Hs(this.Hr),this.ve.Lt(0),this.ve.Ot(this.jr.texture,this.ps.offsetX,this.ps.offsetY,this.jr.texture.width,this.jr.texture.height)):(this.ve.jt(),this.ve.Ot(this.Hr,this.ps.offsetX,this.ps.offsetY,this.Hr.width,this.Hr.height)))}ai(){this.Ye.ss(),this.Hr.resize(this.Ye.width,this.Ye.height),this.ps.ss(),this.jr.ss(),this.ve.Ht(),this.Or!=="manual"&&this.render()}oi(){if(this.Or!=="auto"||!this.qr)return;this.Nr=performance.now();const s=i=>{if(!this.qr)return void(this.Wr=null);const n=i-this.Nr;n>=this.Xr&&(this.render(),this.Nr=i-n%this.Xr),this.qr&&(this.Wr=requestAnimationFrame(s))};this.Wr=requestAnimationFrame(s)}hi(){const s=performance.now();if(this.Qr>0){const i=s-this.Qr;this.Jr.push(i),this.Jr.length>this.Kr&&this.Jr.shift();const n=this.Jr.reduce((o,h)=>o+h,0)/this.Jr.length;this.Yr=1e3/n}this.Qr=s}li(){this.Wr&&(cancelAnimationFrame(this.Wr),this.Wr=null)}renderMode(s){this.Or!==s&&(this.li(),this.Or=s,s==="auto"&&this.qr&&this.oi())}frameRate(s){if(s===void 0)return this.Yr;this.Br=s,this.Xr=1e3/s,this.Or==="auto"&&this.qr&&(this.li(),this.oi())}noLoop(){this.qr&&(this.qr=!1,this.Wr&&(cancelAnimationFrame(this.Wr),this.Wr=null))}loop(){this.qr||(this.qr=!0,this.Or==="auto"&&this.oi())}redraw(s=1){if(C.m(typeof s=="number"&&s>0&&Number.isInteger(s),"Redraw count must be a positive integer.",{method:"redraw",providedValue:s}))for(let i=0;i<s;i++)this.render()}isLooping(){return this.Or==="auto"&&this.qr}draw(s){this.si=s}windowResized(s){this.ri=s}resizeCanvas(s,i){this.ei&&(this.Ye.ss(s,i),this.Hr.resize(this.Ye.width,this.Ye.height),this.ps.ss(),this.jr.ss(),this.ve.Ht(),this.Or!=="manual"&&this.render())}destroy(){this.ti||(this.li(),window.removeEventListener("resize",this.ii),this.ls&&this.ls.disconnect(),this.jr.G(),this.Te.G(),this.Hr.G(),this.ve.G(),this.ti=!0)}get grid(){return this.ps}get font(){return this.Te}get mode(){return this.Or}get pipeline(){return this.jr}get frameCount(){return this.Zr}set frameCount(s){this.Zr=s}get width(){return this.Ye.width}get height(){return this.Ye.height}get canvas(){return this.Ye}get isDisposed(){return this.ti}}class k{constructor(){throw new b("Textmode is a static class and cannot be instantiated.")}static async create(r,s={}){if(!(r==null||r instanceof HTMLCanvasElement||r instanceof HTMLVideoElement||typeof r=="object"))throw new b("First parameter must be HTMLCanvasElement, HTMLVideoElement, or options object.");if(typeof s!="object")throw new b("Second parameter must be an options object.");if(r instanceof HTMLCanvasElement||r instanceof HTMLVideoElement)return H.create(r,s);{const i=r||{};return H.create(null,i)}}static setErrorLevel(r){C._(r)}static get version(){return"0.1.
|
|
63
|
+
`;return i.join(n)}}class At extends z{Dr(r,s){const i=this.Rr(s);this.Xs(r,i,"text/plain;charset=utf-8")}Rr(r){let s=this.Qs(r);return s===".txt"||s.length<=4?this.Zs():s}}class it{constructor(){c(this,"Cr");c(this,"yr");c(this,"$r");this.Cr=new Ft,this.yr=new Mt,this.$r=new At}Fr(r){return{preserveTrailingSpaces:r.preserveTrailingSpaces??!1,lineEnding:r.lineEnding??"lf",emptyCharacter:r.emptyCharacter??" "}}Vr(r,s={}){const i=this.Fr(s),n=this.Cr.Os(r.pipeline),o=this.Cr.Mr(n,r.grid,r.font,i.emptyCharacter);return this.yr.Sr(o,i)}Dr(r,s={}){const i=this.Vr(r,s),n=s.filename||this.$r.Zs();this.$r.Dr(i,n)}}class Pt extends N{kr(r,s=1,i="transparent"){const n=r.canvas;if(s===1&&i==="transparent")return n;const o=document.createElement("canvas"),h=o.getContext("2d"),a=Math.round(n.width*s),u=Math.round(n.height*s);return o.width=a,o.height=u,i!=="transparent"&&(h.fillStyle=i,h.fillRect(0,0,a,u)),h.imageSmoothingEnabled=!1,h.drawImage(n,0,0,n.width,n.height,0,0,a,u),o}}class Ut{Ir(r,s){const i=this.zr(s.format);return s.format==="png"?r.toDataURL(i):r.toDataURL(i,s.quality)}async Er(r,s){return new Promise((i,n)=>{const o=this.zr(s.format),h=a=>{a?i(a):n(Error(`Failed to generate ${s.format.toUpperCase()} blob`))};s.format==="png"?r.toBlob(h,o):r.toBlob(h,o,s.quality)})}zr(r){switch(r){case"png":return"image/png";case"jpg":return"image/jpeg";case"webp":return"image/webp";default:throw Error("Unsupported image format: "+r)}}}const Dt={png:"image/png",jpg:"image/jpeg",webp:"image/webp"},nt={png:".png",jpg:".jpg",webp:".webp"};class St extends z{Gr(r,s,i){this.Pr(r,this.Qs(s)+nt[i])}Pr(r,s){const i=URL.createObjectURL(r);try{const n=document.createElement("a");n.href=i,n.download=s,n.style.display="none",n.rel="noopener",document.body.appendChild(n),n.click(),document.body.removeChild(n)}finally{URL.revokeObjectURL(i)}}Ar(r){return r in Dt&&r in nt}}class $t{constructor(){c(this,"Cr");c(this,"yr");c(this,"$r");this.Cr=new Pt,this.yr=new Ut,this.$r=new St}Fr(r){return{format:r.format??"png",quality:r.quality??1,scale:r.scale??1,backgroundColor:r.backgroundColor??"transparent"}}Ur(r){if(console.log("Validating image export options:",r),!this.$r.Ar(r.format))throw Error(`Saving '${r.format}' files is not supported`);if(r.quality<0||r.quality>1)throw Error("Image quality must be between 0.0 and 1.0");if(r.scale<=0)throw Error("Scale factor must be greater than 0");r.scale>10&&console.warn("Large scale factors may result in very large files and slow performance"),r.format==="jpg"&&r.backgroundColor==="transparent"&&(r.backgroundColor="black")}Lr(r,s={}){const i=this.Fr(s);if(this.Ur(i),i.scale===1&&i.backgroundColor==="transparent")return this.yr.Ir(r.canvas,i);const n=this.Cr.kr(r,i.scale,i.backgroundColor);return this.yr.Ir(n,i)}async Er(r,s={}){const i=this.Fr(s);if(this.Ur(i),i.scale===1&&i.backgroundColor==="transparent")return await this.yr.Er(r.canvas,i);const n=this.Cr.kr(r,i.scale,i.backgroundColor);return await this.yr.Er(n,i)}async Gr(r,s={}){const i=await this.Er(r,s),n=s.format??"png",o=s.filename||this.$r.Zs();this.$r.Gr(i,o,n)}}const It=l=>class extends l{toString(r={}){return new it().Vr({pipeline:this.jr,grid:this.ps,font:this.Te},r)}saveStrings(r={}){new it().Dr({pipeline:this.jr,grid:this.ps,font:this.Te},r)}toSVG(r={}){return new st().Tr(this,r)}saveSVG(r={}){new st().wr(this,r)}async saveCanvas(r,s="png",i={}){await new $t().Gr(this.Ye,{...i,filename:r,format:s})}},Gt=l=>class extends l{async loadFont(r){return this.Te.Oe(r).then(()=>{const s=this.Te.maxGlyphDimensions;this.ps.Ke(s.width,s.height),this.jr.ss()})}fontSize(r){if(!C.m(typeof r=="number"&&r>0,"Font size must be a positive number greater than 0.",{method:"fontSize",providedValue:r})||this.Te.fontSize===r)return;this.Te.He(r);const s=this.Te.maxGlyphDimensions;this.ps.Ke(s.width,s.height),this.jr.ss(),this.ve.Ht()}},kt=l=>class extends l{addConverter(r){return this.jr.add(r)}removeConverter(r){this.jr.remove(r)}};class Lt{constructor(){c(this,"ve");c(this,"Te");c(this,"jr");c(this,"Ye");c(this,"ps")}}class H extends function(s,...i){return i.reduce((n,o)=>o(n),s)}(Lt,yt,It,Gt,kt){constructor(s=null,i={}){super();c(this,"ns");c(this,"Hr");c(this,"ls");c(this,"Or");c(this,"Br");c(this,"Wr",null);c(this,"Nr",0);c(this,"Xr");c(this,"qr",!0);c(this,"Yr",0);c(this,"Qr",0);c(this,"Zr",0);c(this,"Jr",[]);c(this,"Kr",10);c(this,"ti",!1);c(this,"ei",!1);c(this,"si",()=>{});c(this,"ri",()=>{});c(this,"ii");this.ns=s,this.ei=s===null,this.Or=i.renderMode??"auto",this.Br=i.frameRate??60,this.Xr=1e3/this.Br}static async create(s=null,i={}){const n=new this(s,i),o=n.ei?i:void 0;let h,a;n.Ye=new et(n.ns,n.ei,o),n.ve=new lt(n.Ye.fs()),n.ei?(h=i.width||800,a=i.height||600):(h=n.Ye.width||800,a=n.Ye.height||600),n.Hr=n.ve.Ut(h,a),n.Te=new K(n.ve,i.fontSize??16),await n.Te.Ue(i.fontSource);const u=n.Te.maxGlyphDimensions;return n.ps=new tt(n.Ye.canvas,u.width,u.height),n.jr=new rt(n.ve,n.Te,n.ps),n.ni(),n.oi(),n}ni(){this.ii=()=>{this.ei?this.ri():this.ai()},window.addEventListener("resize",this.ii),window.ResizeObserver&&this.ns&&!this.ei&&(this.ls=new ResizeObserver(()=>{this.ai()}),this.ls.observe(this.ns))}render(){this.hi(),this.Zr++,this.ti?console.warn("Cannot render: Required resources have been disposed"):(this.ei?(this.Hr.begin(),this.si(),this.Hr.end()):this.Hr.update(this.ns),this.jr.hasEnabledConverters()?(this.jr.Hs(this.Hr),this.ve.Lt(0),this.ve.Ot(this.jr.texture,this.ps.offsetX,this.ps.offsetY,this.jr.texture.width,this.jr.texture.height)):(this.ve.jt(),this.ve.Ot(this.Hr,this.ps.offsetX,this.ps.offsetY,this.Hr.width,this.Hr.height)))}ai(){this.Ye.ss(),this.Hr.resize(this.Ye.width,this.Ye.height),this.ps.ss(),this.jr.ss(),this.ve.Ht(),this.Or!=="manual"&&this.render()}oi(){if(this.Or!=="auto"||!this.qr)return;this.Nr=performance.now();const s=i=>{if(!this.qr)return void(this.Wr=null);const n=i-this.Nr;n>=this.Xr&&(this.render(),this.Nr=i-n%this.Xr),this.qr&&(this.Wr=requestAnimationFrame(s))};this.Wr=requestAnimationFrame(s)}hi(){const s=performance.now();if(this.Qr>0){const i=s-this.Qr;this.Jr.push(i),this.Jr.length>this.Kr&&this.Jr.shift();const n=this.Jr.reduce((o,h)=>o+h,0)/this.Jr.length;this.Yr=1e3/n}this.Qr=s}li(){this.Wr&&(cancelAnimationFrame(this.Wr),this.Wr=null)}renderMode(s){this.Or!==s&&(this.li(),this.Or=s,s==="auto"&&this.qr&&this.oi())}frameRate(s){if(s===void 0)return this.Yr;this.Br=s,this.Xr=1e3/s,this.Or==="auto"&&this.qr&&(this.li(),this.oi())}noLoop(){this.qr&&(this.qr=!1,this.Wr&&(cancelAnimationFrame(this.Wr),this.Wr=null))}loop(){this.qr||(this.qr=!0,this.Or==="auto"&&this.oi())}redraw(s=1){if(C.m(typeof s=="number"&&s>0&&Number.isInteger(s),"Redraw count must be a positive integer.",{method:"redraw",providedValue:s}))for(let i=0;i<s;i++)this.render()}isLooping(){return this.Or==="auto"&&this.qr}draw(s){this.si=s}windowResized(s){this.ri=s}resizeCanvas(s,i){this.ei&&(this.Ye.ss(s,i),this.Hr.resize(this.Ye.width,this.Ye.height),this.ps.ss(),this.jr.ss(),this.ve.Ht(),this.Or!=="manual"&&this.render())}destroy(){this.ti||(this.li(),window.removeEventListener("resize",this.ii),this.ls&&this.ls.disconnect(),this.jr.G(),this.Te.G(),this.Hr.G(),this.ve.G(),this.ti=!0)}get grid(){return this.ps}get font(){return this.Te}get mode(){return this.Or}get pipeline(){return this.jr}get frameCount(){return this.Zr}set frameCount(s){this.Zr=s}get width(){return this.Ye.width}get height(){return this.Ye.height}get canvas(){return this.Ye}get isDisposed(){return this.ti}}class k{constructor(){throw new b("Textmode is a static class and cannot be instantiated.")}static async create(r,s={}){if(!(r==null||r instanceof HTMLCanvasElement||r instanceof HTMLVideoElement||typeof r=="object"))throw new b("First parameter must be HTMLCanvasElement, HTMLVideoElement, or options object.");if(typeof s!="object")throw new b("Second parameter must be an options object.");if(r instanceof HTMLCanvasElement||r instanceof HTMLVideoElement)return H.create(r,s);{const i=r||{};return H.create(null,i)}}static setErrorLevel(r){C._(r)}static get version(){return"0.1.9-beta.2"}}const Yt=Object.freeze(Object.defineProperty({__proto__:null},Symbol.toStringTag,{value:"Module"})),Bt=k.create,jt=k.setErrorLevel,Vt=k.version;w.TextmodeCanvas=et,w.TextmodeConversionPipeline=rt,w.TextmodeErrorLevel=U,w.TextmodeFont=K,w.TextmodeGrid=tt,w.Textmodifier=H,w.converters=Ct,w.create=Bt,w.default=k,w.export=Yt,w.setErrorLevel=jt,w.textmode=k,w.version=Vt,Object.defineProperties(w,{ci:{value:!0},[Symbol.toStringTag]:{value:"Module"}})},typeof exports=="object"&&typeof module<"u"?e(exports):typeof define=="function"&&define.amd?define(["exports"],e):e((t=typeof globalThis<"u"?globalThis:t||self).textmode={});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Mixin } from './TextmodifierMixin';
|
|
2
|
-
import type { Shader } from '../../rendering';
|
|
2
|
+
import type { Framebuffer, Shader } from '../../rendering';
|
|
3
|
+
import type { FramebufferOptions } from '../../rendering/webgl/Framebuffer';
|
|
3
4
|
/**
|
|
4
5
|
* Interface for rendering capabilities that will be mixed into Textmodifier
|
|
5
6
|
*/
|
|
@@ -401,6 +402,26 @@ export interface RenderingCapabilities {
|
|
|
401
402
|
* @param value The value to set for the uniform variable.
|
|
402
403
|
*/
|
|
403
404
|
setUniform(name: string, value: any): void;
|
|
405
|
+
/**
|
|
406
|
+
* Draw an image to the canvas.
|
|
407
|
+
* @param source The image source
|
|
408
|
+
* @param posX The x position to draw the image
|
|
409
|
+
* @param posY The y position to draw the image
|
|
410
|
+
* @param width The width to draw the image (optional)
|
|
411
|
+
* @param height The height to draw the image (optional)
|
|
412
|
+
*/
|
|
413
|
+
image(source: Framebuffer, posX: number, posY: number, width?: number, height?: number): void;
|
|
414
|
+
/**
|
|
415
|
+
* Clear the canvas.
|
|
416
|
+
*/
|
|
417
|
+
clear(): void;
|
|
418
|
+
/**
|
|
419
|
+
* Create a framebuffer.
|
|
420
|
+
* @param width The width in pixels
|
|
421
|
+
* @param height The height in pixels
|
|
422
|
+
* @param options Additional options for the framebuffer
|
|
423
|
+
*/
|
|
424
|
+
createFramebuffer(width: number, height: number, options: FramebufferOptions): Framebuffer;
|
|
404
425
|
}
|
|
405
426
|
/**
|
|
406
427
|
* Mixin that adds rendering capabilities to a class by delegating to GLRenderer
|