textmode.js 0.1.3 → 0.1.4-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.esm.js +356 -161
- package/dist/textmode.esm.min.js +275 -80
- package/dist/textmode.umd.js +6 -6
- package/dist/textmode.umd.min.js +13 -13
- package/dist/types/Textmode.d.ts +14 -0
- package/dist/types/rendering/webgl/Framebuffer.d.ts +9 -0
- package/dist/types/rendering/webgl/Renderer.d.ts +9 -0
- package/dist/types/rendering/webgl/Shader.d.ts +9 -0
- package/dist/types/textmode/Canvas.d.ts +9 -0
- package/dist/types/textmode/ConversionPipeline.d.ts +9 -0
- package/dist/types/textmode/Grid.d.ts +9 -0
- package/dist/types/textmode/Textmodifier.d.ts +32 -0
- package/dist/types/textmode/converters/Converter.d.ts +9 -0
- package/dist/types/textmode/font/TextmodeFont.d.ts +9 -0
- package/package.json +1 -1
package/dist/textmode.esm.min.js
CHANGED
|
@@ -104,8 +104,8 @@ const E = class E {
|
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
106
|
o(E, "_instance", null);
|
|
107
|
-
let
|
|
108
|
-
const x =
|
|
107
|
+
let $ = E;
|
|
108
|
+
const x = $.getInstance();
|
|
109
109
|
class oe {
|
|
110
110
|
constructor(e, t, r = t, i = {}) {
|
|
111
111
|
o(this, "gl");
|
|
@@ -201,6 +201,20 @@ class oe {
|
|
|
201
201
|
return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, r, i, s.RGBA, s.UNSIGNED_BYTE, a), s.bindFramebuffer(s.FRAMEBUFFER, n), a;
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Dispose of WebGL resources used by this framebuffer.
|
|
206
|
+
* This method is idempotent and safe to call multiple times.
|
|
207
|
+
*/
|
|
208
|
+
dispose() {
|
|
209
|
+
const { gl: e } = this;
|
|
210
|
+
this._framebuffer && (e.deleteFramebuffer(this._framebuffer), this._framebuffer = null), this._texture && (e.deleteTexture(this._texture), this._texture = null), this._pixels = null;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Check if this framebuffer has been disposed
|
|
214
|
+
*/
|
|
215
|
+
get isDisposed() {
|
|
216
|
+
return this._framebuffer === null || this._texture === null;
|
|
217
|
+
}
|
|
204
218
|
get framebuffer() {
|
|
205
219
|
return this._framebuffer;
|
|
206
220
|
}
|
|
@@ -225,7 +239,7 @@ class Q {
|
|
|
225
239
|
this.gl = e, this.x = t, this.y = r;
|
|
226
240
|
}
|
|
227
241
|
}
|
|
228
|
-
class
|
|
242
|
+
class A {
|
|
229
243
|
constructor(e, t, r, i, s) {
|
|
230
244
|
/** The WebGL rendering context */
|
|
231
245
|
o(this, "gl");
|
|
@@ -239,9 +253,9 @@ class M {
|
|
|
239
253
|
const a = e.getParameter(e.VIEWPORT), n = a[2], l = a[3], c = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, u = t / n * 2 - 1, d = (t + i) / n * 2 - 1;
|
|
240
254
|
let f, g;
|
|
241
255
|
c ? (f = r / l * 2 - 1, g = (r + s) / l * 2 - 1) : (f = 1 - r / l * 2, g = 1 - (r + s) / l * 2);
|
|
242
|
-
let _,
|
|
243
|
-
|
|
244
|
-
const v = this.generateVertices(_,
|
|
256
|
+
let p, _, b, C;
|
|
257
|
+
p = u, b = d, _ = f, C = g;
|
|
258
|
+
const v = this.generateVertices(p, _, b, C);
|
|
245
259
|
this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, v, e.STATIC_DRAW);
|
|
246
260
|
}
|
|
247
261
|
/**
|
|
@@ -303,7 +317,7 @@ class he extends Q {
|
|
|
303
317
|
* Render the filled rectangle using the existing Rectangle geometry.
|
|
304
318
|
*/
|
|
305
319
|
renderFill() {
|
|
306
|
-
new
|
|
320
|
+
new A(this.gl, this.x, this.y, this.width, this.height).render();
|
|
307
321
|
}
|
|
308
322
|
/**
|
|
309
323
|
* Render the stroke rectangle as four separate Rectangle instances for each edge.
|
|
@@ -312,7 +326,7 @@ class he extends Q {
|
|
|
312
326
|
*/
|
|
313
327
|
renderStroke(t) {
|
|
314
328
|
if (t <= 0) return;
|
|
315
|
-
const r = new
|
|
329
|
+
const r = new A(this.gl, this.x, this.y, this.width, t), i = new A(this.gl, this.x + this.width - t, this.y, t, this.height), s = new A(this.gl, this.x, this.y + this.height - t, this.width, t), a = new A(this.gl, this.x, this.y, t, this.height);
|
|
316
330
|
r.render(), i.render(), s.render(), a.render();
|
|
317
331
|
}
|
|
318
332
|
}
|
|
@@ -333,9 +347,9 @@ class le {
|
|
|
333
347
|
this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, ie, e.STATIC_DRAW);
|
|
334
348
|
return;
|
|
335
349
|
}
|
|
336
|
-
const
|
|
350
|
+
const p = d / g, b = -(f / g), C = p, v = a / 2, w = t + b * v, D = r + C * v, R = t - b * v, y = r - C * v, P = i + b * v, M = s + C * v, Z = i - b * v, W = s - C * v, J = w / l * 2 - 1, K = R / l * 2 - 1, ee = P / l * 2 - 1, te = Z / l * 2 - 1;
|
|
337
351
|
let B, G, V, k;
|
|
338
|
-
u ? (B =
|
|
352
|
+
u ? (B = D / c * 2 - 1, G = y / c * 2 - 1, V = M / c * 2 - 1, k = W / c * 2 - 1) : (B = 1 - D / c * 2, G = 1 - y / c * 2, V = 1 - M / c * 2, k = 1 - W / c * 2);
|
|
339
353
|
const re = this.generateLineVertices(
|
|
340
354
|
J,
|
|
341
355
|
B,
|
|
@@ -590,6 +604,19 @@ class T {
|
|
|
590
604
|
get glProgram() {
|
|
591
605
|
return this.program;
|
|
592
606
|
}
|
|
607
|
+
/**
|
|
608
|
+
* Dispose of WebGL resources used by this shader.
|
|
609
|
+
* This method is idempotent and safe to call multiple times.
|
|
610
|
+
*/
|
|
611
|
+
dispose() {
|
|
612
|
+
this.program && (this.gl.deleteProgram(this.program), this.program = null), this.uniformLocations.clear(), this.attributeLocations.clear(), this.textureUnitCounter = 0;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Check if this shader has been disposed
|
|
616
|
+
*/
|
|
617
|
+
get isDisposed() {
|
|
618
|
+
return this.program === null;
|
|
619
|
+
}
|
|
593
620
|
/**
|
|
594
621
|
* Reset texture unit counter (useful when starting a new frame)
|
|
595
622
|
*/
|
|
@@ -732,8 +759,8 @@ class fe {
|
|
|
732
759
|
const s = new he(this.gl, e, t, r, i);
|
|
733
760
|
if (this.currentShader !== null) {
|
|
734
761
|
if (this.currentRotation !== 0) {
|
|
735
|
-
const { centerX: d, centerY: f, radians: g, aspectRatio:
|
|
736
|
-
this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio",
|
|
762
|
+
const { centerX: d, centerY: f, radians: g, aspectRatio: p } = this.calculateRotationParams(e, t, r, i);
|
|
763
|
+
this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", p);
|
|
737
764
|
} else
|
|
738
765
|
this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
|
|
739
766
|
s.renderFill(), this.currentShader = null;
|
|
@@ -755,15 +782,15 @@ class fe {
|
|
|
755
782
|
const s = new ce(this.gl, e, t, r, i);
|
|
756
783
|
if (this.currentShader !== null) {
|
|
757
784
|
if (this.currentRotation !== 0) {
|
|
758
|
-
const
|
|
759
|
-
this.setUniform("u_rotation", R), this.setUniform("u_center", [w,
|
|
785
|
+
const _ = (e + r) / 2, b = (t + i) / 2, C = Math.abs(r - e), v = Math.abs(i - t), { centerX: w, centerY: D, radians: R, aspectRatio: y } = this.calculateRotationParams(_ - C / 2, b - v / 2, C, v);
|
|
786
|
+
this.setUniform("u_rotation", R), this.setUniform("u_center", [w, D]), this.setUniform("u_aspectRatio", y);
|
|
760
787
|
} else
|
|
761
788
|
this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
|
|
762
789
|
s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
|
|
763
790
|
return;
|
|
764
791
|
}
|
|
765
|
-
const a = this.solidColorShader, n = (e + r) / 2, l = (t + i) / 2, c = Math.abs(r - e), u = Math.abs(i - t), { centerX: d, centerY: f, radians: g, aspectRatio:
|
|
766
|
-
this.shader(a), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio",
|
|
792
|
+
const a = this.solidColorShader, n = (e + r) / 2, l = (t + i) / 2, c = Math.abs(r - e), u = Math.abs(i - t), { centerX: d, centerY: f, radians: g, aspectRatio: p } = this.calculateRotationParams(n - c / 2, l - u / 2, c, u);
|
|
793
|
+
this.shader(a), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", p), s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
|
|
767
794
|
}
|
|
768
795
|
/**
|
|
769
796
|
* Calculate rotation parameters for built-in shaders (NDC coordinates)
|
|
@@ -772,8 +799,8 @@ class fe {
|
|
|
772
799
|
const s = this.gl.getParameter(this.gl.VIEWPORT), a = s[2], n = s[3], l = a / n, c = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING) !== null, u = e + r / 2, d = t + i / 2, f = u / a * 2 - 1;
|
|
773
800
|
let g;
|
|
774
801
|
c ? g = d / n * 2 - 1 : g = 1 - d / n * 2;
|
|
775
|
-
const
|
|
776
|
-
return { centerX: f, centerY: g, radians:
|
|
802
|
+
const p = this.currentRotation * Math.PI / 180;
|
|
803
|
+
return { centerX: f, centerY: g, radians: p, aspectRatio: l };
|
|
777
804
|
}
|
|
778
805
|
/**
|
|
779
806
|
* Create a new framebuffer
|
|
@@ -805,6 +832,19 @@ class fe {
|
|
|
805
832
|
get context() {
|
|
806
833
|
return this.gl;
|
|
807
834
|
}
|
|
835
|
+
/**
|
|
836
|
+
* Dispose of all WebGL resources managed by this renderer.
|
|
837
|
+
* This method is idempotent and safe to call multiple times.
|
|
838
|
+
*/
|
|
839
|
+
dispose() {
|
|
840
|
+
this.imageShader && !this.imageShader.isDisposed && this.imageShader.dispose(), this.solidColorShader && !this.solidColorShader.isDisposed && this.solidColorShader.dispose(), this.imageShader = null, this.solidColorShader = null, this.currentShader = null, this.stateStack = [];
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* Check if this renderer has been disposed
|
|
844
|
+
*/
|
|
845
|
+
get isDisposed() {
|
|
846
|
+
return this.imageShader === null || this.solidColorShader === null;
|
|
847
|
+
}
|
|
808
848
|
/**
|
|
809
849
|
* Render a framebuffer at a specific position with optional scaling
|
|
810
850
|
*/
|
|
@@ -834,8 +874,8 @@ m.parse = function(h) {
|
|
|
834
874
|
for (var f in u) {
|
|
835
875
|
var g = m.findTable(s, f, n);
|
|
836
876
|
if (g) {
|
|
837
|
-
var
|
|
838
|
-
|
|
877
|
+
var p = g[0], _ = l[p];
|
|
878
|
+
_ == null && (_ = u[f].parseTab(s, p, g[1], d)), d[f] = l[p] = _;
|
|
839
879
|
}
|
|
840
880
|
}
|
|
841
881
|
return d;
|
|
@@ -900,15 +940,15 @@ m.T.cmap = {
|
|
|
900
940
|
e += 2;
|
|
901
941
|
var f = i.readUint(h, e);
|
|
902
942
|
e += 4;
|
|
903
|
-
var g = "p" + u + "e" + d,
|
|
904
|
-
if (
|
|
905
|
-
|
|
906
|
-
var
|
|
943
|
+
var g = "p" + u + "e" + d, p = l.indexOf(f);
|
|
944
|
+
if (p == -1) {
|
|
945
|
+
p = r.tables.length;
|
|
946
|
+
var _ = {};
|
|
907
947
|
l.push(f);
|
|
908
|
-
var
|
|
909
|
-
|
|
948
|
+
var b = _.format = s(h, f);
|
|
949
|
+
b == 4 ? _ = a.parse4(h, f, _) : b == 12 && (_ = a.parse12(h, f, _)), r.tables.push(_);
|
|
910
950
|
}
|
|
911
|
-
r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] =
|
|
951
|
+
r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] = p;
|
|
912
952
|
}
|
|
913
953
|
return r;
|
|
914
954
|
},
|
|
@@ -1022,16 +1062,16 @@ m.T.glyf = {
|
|
|
1022
1062
|
}
|
|
1023
1063
|
a.xs = [];
|
|
1024
1064
|
for (var n = 0; n < c; n++) {
|
|
1025
|
-
var g = (a.flags[n] & 2) != 0,
|
|
1026
|
-
g ? (a.xs.push(
|
|
1065
|
+
var g = (a.flags[n] & 2) != 0, p = (a.flags[n] & 16) != 0;
|
|
1066
|
+
g ? (a.xs.push(p ? r[s] : -r[s]), s++) : p ? a.xs.push(0) : (a.xs.push(t.readShort(r, s)), s += 2);
|
|
1027
1067
|
}
|
|
1028
1068
|
a.ys = [];
|
|
1029
1069
|
for (var n = 0; n < c; n++) {
|
|
1030
|
-
var g = (a.flags[n] & 4) != 0,
|
|
1031
|
-
g ? (a.ys.push(
|
|
1070
|
+
var g = (a.flags[n] & 4) != 0, p = (a.flags[n] & 32) != 0;
|
|
1071
|
+
g ? (a.ys.push(p ? r[s] : -r[s]), s++) : p ? a.ys.push(0) : (a.ys.push(t.readShort(r, s)), s += 2);
|
|
1032
1072
|
}
|
|
1033
|
-
for (var
|
|
1034
|
-
|
|
1073
|
+
for (var _ = 0, b = 0, n = 0; n < c; n++)
|
|
1074
|
+
_ += a.xs[n], b += a.ys[n], a.xs[n] = _, a.ys[n] = b;
|
|
1035
1075
|
} else
|
|
1036
1076
|
a.parts = [];
|
|
1037
1077
|
return a;
|
|
@@ -1204,7 +1244,7 @@ class ge {
|
|
|
1204
1244
|
this._textureContext.putImageData(t, 0, 0);
|
|
1205
1245
|
}
|
|
1206
1246
|
}
|
|
1207
|
-
class
|
|
1247
|
+
class _e {
|
|
1208
1248
|
/**
|
|
1209
1249
|
* Creates a new MetricsCalculation instance.
|
|
1210
1250
|
*/
|
|
@@ -1234,7 +1274,7 @@ class pe {
|
|
|
1234
1274
|
};
|
|
1235
1275
|
}
|
|
1236
1276
|
}
|
|
1237
|
-
class
|
|
1277
|
+
class pe {
|
|
1238
1278
|
/**
|
|
1239
1279
|
* Creates TextmodeCharacter objects with unique color assignments.
|
|
1240
1280
|
* @param characters Array of character strings
|
|
@@ -1346,7 +1386,7 @@ class xe {
|
|
|
1346
1386
|
o(this, "_textureAtlas");
|
|
1347
1387
|
o(this, "_metricsCalculator");
|
|
1348
1388
|
o(this, "_characterColorMapper");
|
|
1349
|
-
this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new
|
|
1389
|
+
this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new _e(), this._characterColorMapper = new pe();
|
|
1350
1390
|
}
|
|
1351
1391
|
/**
|
|
1352
1392
|
* Initializes the font manager by loading the font and creating the texture atlas.
|
|
@@ -1484,6 +1524,19 @@ class xe {
|
|
|
1484
1524
|
get maxGlyphDimensions() {
|
|
1485
1525
|
return this._maxGlyphDimensions;
|
|
1486
1526
|
}
|
|
1527
|
+
/**
|
|
1528
|
+
* Dispose of all resources used by this font manager.
|
|
1529
|
+
* This method is idempotent and safe to call multiple times.
|
|
1530
|
+
*/
|
|
1531
|
+
dispose() {
|
|
1532
|
+
this._fontFramebuffer && !this._fontFramebuffer.isDisposed && this._fontFramebuffer.dispose(), this._fontFace && document.fonts.has(this._fontFace) && document.fonts.delete(this._fontFace), this._fontFramebuffer = null, this._fontFace = null, this._font = null, this._characters = [], this._maxGlyphDimensions = { width: 0, height: 0 }, this._textureColumns = 0, this._textureRows = 0;
|
|
1533
|
+
}
|
|
1534
|
+
/**
|
|
1535
|
+
* Check if this font manager has been disposed
|
|
1536
|
+
*/
|
|
1537
|
+
get isDisposed() {
|
|
1538
|
+
return this._fontFramebuffer === null || this._font === null;
|
|
1539
|
+
}
|
|
1487
1540
|
/** Returns the font size used for rendering. */
|
|
1488
1541
|
get fontSize() {
|
|
1489
1542
|
return this._fontSize;
|
|
@@ -1598,6 +1651,19 @@ class ve {
|
|
|
1598
1651
|
get cellHeight() {
|
|
1599
1652
|
return this._cellHeight;
|
|
1600
1653
|
}
|
|
1654
|
+
/**
|
|
1655
|
+
* Dispose of this TextmodeGrid and clean up references.
|
|
1656
|
+
* This method is idempotent and safe to call multiple times.
|
|
1657
|
+
*/
|
|
1658
|
+
dispose() {
|
|
1659
|
+
this._canvas = null, this._cols = 0, this._rows = 0, this._width = 0, this._height = 0, this._offsetX = 0, this._offsetY = 0, this._cellWidth = 0, this._cellHeight = 0;
|
|
1660
|
+
}
|
|
1661
|
+
/**
|
|
1662
|
+
* Check if this TextmodeGrid has been disposed
|
|
1663
|
+
*/
|
|
1664
|
+
get isDisposed() {
|
|
1665
|
+
return this._canvas === null;
|
|
1666
|
+
}
|
|
1601
1667
|
/** Returns the number of columns in the grid. */
|
|
1602
1668
|
get cols() {
|
|
1603
1669
|
return this._cols;
|
|
@@ -1623,7 +1689,7 @@ class ve {
|
|
|
1623
1689
|
return this._offsetY;
|
|
1624
1690
|
}
|
|
1625
1691
|
}
|
|
1626
|
-
class
|
|
1692
|
+
class be {
|
|
1627
1693
|
constructor(e, t = !1, r = {}) {
|
|
1628
1694
|
o(this, "_canvas");
|
|
1629
1695
|
o(this, "captureSource");
|
|
@@ -1633,8 +1699,8 @@ class Ce {
|
|
|
1633
1699
|
createCanvas(e, t) {
|
|
1634
1700
|
var i;
|
|
1635
1701
|
const r = document.createElement("canvas");
|
|
1636
|
-
if (r.className = "textmodeCanvas", this._isStandalone)
|
|
1637
|
-
r.width = e || 800, r.height = t || 600,
|
|
1702
|
+
if (r.className = "textmodeCanvas", r.style.imageRendering = "pixelated", this._isStandalone)
|
|
1703
|
+
r.width = e || 800, r.height = t || 600, document.body.appendChild(r);
|
|
1638
1704
|
else {
|
|
1639
1705
|
const s = this.captureSource.getBoundingClientRect();
|
|
1640
1706
|
let a = Math.round(s.width), n = Math.round(s.height);
|
|
@@ -1642,7 +1708,7 @@ class Ce {
|
|
|
1642
1708
|
const u = this.captureSource;
|
|
1643
1709
|
(a === 0 || n === 0) && u.videoWidth > 0 && u.videoHeight > 0 && (a = u.videoWidth, n = u.videoHeight);
|
|
1644
1710
|
}
|
|
1645
|
-
r.width = a, r.height = n, r.style.
|
|
1711
|
+
r.width = a, r.height = n, r.style.position = "absolute", r.style.pointerEvents = "none";
|
|
1646
1712
|
const l = window.getComputedStyle(this.captureSource);
|
|
1647
1713
|
let c = parseInt(l.zIndex || "0", 10);
|
|
1648
1714
|
isNaN(c) && (c = 0), r.style.zIndex = (c + 1).toString(), this.positionOverlayCanvas(r), (i = this.captureSource.parentNode) == null || i.insertBefore(r, this.captureSource.nextSibling);
|
|
@@ -1660,7 +1726,7 @@ class Ce {
|
|
|
1660
1726
|
}
|
|
1661
1727
|
resize(e, t) {
|
|
1662
1728
|
if (this._isStandalone)
|
|
1663
|
-
this._canvas.width = e ?? this._canvas.width, this._canvas.height = t ?? this._canvas.height
|
|
1729
|
+
this._canvas.width = e ?? this._canvas.width, this._canvas.height = t ?? this._canvas.height;
|
|
1664
1730
|
else {
|
|
1665
1731
|
const r = this.captureSource.getBoundingClientRect();
|
|
1666
1732
|
let i = Math.round(r.width), s = Math.round(r.height);
|
|
@@ -1668,7 +1734,7 @@ class Ce {
|
|
|
1668
1734
|
const a = this.captureSource;
|
|
1669
1735
|
(i === 0 || s === 0) && a.videoWidth > 0 && a.videoHeight > 0 && (i = a.videoWidth, s = a.videoHeight);
|
|
1670
1736
|
}
|
|
1671
|
-
this._canvas.width = i, this._canvas.height = s, this.
|
|
1737
|
+
this._canvas.width = i, this._canvas.height = s, this.positionOverlayCanvas(this._canvas);
|
|
1672
1738
|
}
|
|
1673
1739
|
}
|
|
1674
1740
|
/**
|
|
@@ -1688,6 +1754,27 @@ class Ce {
|
|
|
1688
1754
|
throw new F("WebGL context could not be created. Ensure your browser supports WebGL.");
|
|
1689
1755
|
return t;
|
|
1690
1756
|
}
|
|
1757
|
+
/**
|
|
1758
|
+
* Dispose of this TextmodeCanvas and clean up all resources.
|
|
1759
|
+
* This method is idempotent and safe to call multiple times.
|
|
1760
|
+
*/
|
|
1761
|
+
dispose() {
|
|
1762
|
+
if (this._canvas) {
|
|
1763
|
+
const e = this._canvas.getContext("webgl") || this._canvas.getContext("webgl2");
|
|
1764
|
+
if (e) {
|
|
1765
|
+
const t = e.getExtension("WEBGL_lose_context");
|
|
1766
|
+
t && t.loseContext();
|
|
1767
|
+
}
|
|
1768
|
+
this._canvas.parentNode && this._canvas.parentNode.removeChild(this._canvas), this._canvas = null;
|
|
1769
|
+
}
|
|
1770
|
+
this.captureSource = null;
|
|
1771
|
+
}
|
|
1772
|
+
/**
|
|
1773
|
+
* Check if this TextmodeCanvas has been disposed
|
|
1774
|
+
*/
|
|
1775
|
+
get isDisposed() {
|
|
1776
|
+
return this._canvas === null;
|
|
1777
|
+
}
|
|
1691
1778
|
get canvas() {
|
|
1692
1779
|
return this._canvas;
|
|
1693
1780
|
}
|
|
@@ -1745,6 +1832,19 @@ class U {
|
|
|
1745
1832
|
disable() {
|
|
1746
1833
|
this.enabled(!1);
|
|
1747
1834
|
}
|
|
1835
|
+
/**
|
|
1836
|
+
* Dispose of all framebuffers used by this converter.
|
|
1837
|
+
* This method is idempotent and safe to call multiple times.
|
|
1838
|
+
*/
|
|
1839
|
+
dispose() {
|
|
1840
|
+
this._characterFramebuffer && !this._characterFramebuffer.isDisposed && this._characterFramebuffer.dispose(), this._primaryColorFramebuffer && !this._primaryColorFramebuffer.isDisposed && this._primaryColorFramebuffer.dispose(), this._secondaryColorFramebuffer && !this._secondaryColorFramebuffer.isDisposed && this._secondaryColorFramebuffer.dispose(), this._rotationFramebuffer && !this._rotationFramebuffer.isDisposed && this._rotationFramebuffer.dispose(), this._transformFramebuffer && !this._transformFramebuffer.isDisposed && this._transformFramebuffer.dispose(), this._characterFramebuffer = null, this._primaryColorFramebuffer = null, this._secondaryColorFramebuffer = null, this._rotationFramebuffer = null, this._transformFramebuffer = null;
|
|
1841
|
+
}
|
|
1842
|
+
/**
|
|
1843
|
+
* Check if this converter has been disposed
|
|
1844
|
+
*/
|
|
1845
|
+
get isDisposed() {
|
|
1846
|
+
return this._characterFramebuffer === null;
|
|
1847
|
+
}
|
|
1748
1848
|
/** Returns the framebuffer containing character data. */
|
|
1749
1849
|
get characterFramebuffer() {
|
|
1750
1850
|
return this._characterFramebuffer;
|
|
@@ -1770,7 +1870,7 @@ class U {
|
|
|
1770
1870
|
return this._options;
|
|
1771
1871
|
}
|
|
1772
1872
|
}
|
|
1773
|
-
class
|
|
1873
|
+
class Ce {
|
|
1774
1874
|
/**
|
|
1775
1875
|
* Create a new color palette instance.
|
|
1776
1876
|
* @param renderer The renderer instance.
|
|
@@ -1829,7 +1929,7 @@ class X extends U {
|
|
|
1829
1929
|
constructor(t, r, i, s = {}) {
|
|
1830
1930
|
super(t, r, i, s);
|
|
1831
1931
|
o(this, "palette");
|
|
1832
|
-
this.palette = new
|
|
1932
|
+
this.palette = new Ce(this.renderer, this.fontManager.getCharacterColors(" .:-=+*%@#"));
|
|
1833
1933
|
}
|
|
1834
1934
|
/**
|
|
1835
1935
|
* Sets the characters used for mapping.
|
|
@@ -2167,6 +2267,21 @@ class Ue {
|
|
|
2167
2267
|
for (const e of this.converters)
|
|
2168
2268
|
e.converter.enable();
|
|
2169
2269
|
}
|
|
2270
|
+
/**
|
|
2271
|
+
* Dispose of all resources used by this conversion pipeline.
|
|
2272
|
+
* This method is idempotent and safe to call multiple times.
|
|
2273
|
+
*/
|
|
2274
|
+
dispose() {
|
|
2275
|
+
for (const e of this.converters)
|
|
2276
|
+
e.converter && !e.converter.isDisposed && e.converter.dispose();
|
|
2277
|
+
this._characterFramebuffer && !this._characterFramebuffer.isDisposed && this._characterFramebuffer.dispose(), this._primaryColorFramebuffer && !this._primaryColorFramebuffer.isDisposed && this._primaryColorFramebuffer.dispose(), this._secondaryColorFramebuffer && !this._secondaryColorFramebuffer.isDisposed && this._secondaryColorFramebuffer.dispose(), this._rotationFramebuffer && !this._rotationFramebuffer.isDisposed && this._rotationFramebuffer.dispose(), this._transformFramebuffer && !this._transformFramebuffer.isDisposed && this._transformFramebuffer.dispose(), this._resultFramebuffer && !this._resultFramebuffer.isDisposed && this._resultFramebuffer.dispose(), this._asciiShader && !this._asciiShader.isDisposed && this._asciiShader.dispose(), this.converters = [], this._characterFramebuffer = null, this._primaryColorFramebuffer = null, this._secondaryColorFramebuffer = null, this._rotationFramebuffer = null, this._transformFramebuffer = null, this._resultFramebuffer = null, this._asciiShader = null;
|
|
2278
|
+
}
|
|
2279
|
+
/**
|
|
2280
|
+
* Check if this conversion pipeline has been disposed
|
|
2281
|
+
*/
|
|
2282
|
+
get isDisposed() {
|
|
2283
|
+
return this._resultFramebuffer === null || this._asciiShader === null;
|
|
2284
|
+
}
|
|
2170
2285
|
/** Returns the character framebuffer containing the combined result of all converters. */
|
|
2171
2286
|
get characterFramebuffer() {
|
|
2172
2287
|
return this._characterFramebuffer;
|
|
@@ -2287,7 +2402,7 @@ class N {
|
|
|
2287
2402
|
return `'textmode-export'-${this.generateTimestamp()}`;
|
|
2288
2403
|
}
|
|
2289
2404
|
}
|
|
2290
|
-
class
|
|
2405
|
+
class De extends H {
|
|
2291
2406
|
/**
|
|
2292
2407
|
* Extracts transform data from transform pixels
|
|
2293
2408
|
* @param transformPixels Transform framebuffer pixels
|
|
@@ -2357,7 +2472,7 @@ class Ae extends H {
|
|
|
2357
2472
|
return r;
|
|
2358
2473
|
}
|
|
2359
2474
|
}
|
|
2360
|
-
class
|
|
2475
|
+
class Ae {
|
|
2361
2476
|
/**
|
|
2362
2477
|
* Gets the glyph index for a given Unicode code point in a Typr.js font
|
|
2363
2478
|
* @param fontData The Typr.js font data
|
|
@@ -2435,22 +2550,22 @@ class Me {
|
|
|
2435
2550
|
const f = n[d];
|
|
2436
2551
|
if (!(f < u)) {
|
|
2437
2552
|
if (f >= u) {
|
|
2438
|
-
const g = t + s[u] * i,
|
|
2439
|
-
c += `M${g.toFixed(2)},${
|
|
2440
|
-
let
|
|
2441
|
-
for (;
|
|
2442
|
-
if ((l[
|
|
2443
|
-
const
|
|
2444
|
-
c += `L${
|
|
2553
|
+
const g = t + s[u] * i, p = r - a[u] * i;
|
|
2554
|
+
c += `M${g.toFixed(2)},${p.toFixed(2)}`;
|
|
2555
|
+
let _ = u + 1;
|
|
2556
|
+
for (; _ <= f; )
|
|
2557
|
+
if ((l[_] & 1) !== 0) {
|
|
2558
|
+
const C = t + s[_] * i, v = r - a[_] * i;
|
|
2559
|
+
c += `L${C.toFixed(2)},${v.toFixed(2)}`, _++;
|
|
2445
2560
|
} else {
|
|
2446
|
-
const
|
|
2447
|
-
let w =
|
|
2561
|
+
const C = t + s[_] * i, v = r - a[_] * i;
|
|
2562
|
+
let w = _ + 1 > f ? u : _ + 1;
|
|
2448
2563
|
if ((l[w] & 1) !== 0) {
|
|
2449
2564
|
const R = t + s[w] * i, y = r - a[w] * i;
|
|
2450
|
-
c += `Q${
|
|
2565
|
+
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${R.toFixed(2)},${y.toFixed(2)}`, _ = w + 1;
|
|
2451
2566
|
} else {
|
|
2452
|
-
const R = t + s[w] * i, y = r - a[w] * i, P = (
|
|
2453
|
-
c += `Q${
|
|
2567
|
+
const R = t + s[w] * i, y = r - a[w] * i, P = (C + R) / 2, M = (v + y) / 2;
|
|
2568
|
+
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${P.toFixed(2)},${M.toFixed(2)}`, _ = w;
|
|
2454
2569
|
}
|
|
2455
2570
|
}
|
|
2456
2571
|
c += "Z";
|
|
@@ -2506,10 +2621,10 @@ class Me {
|
|
|
2506
2621
|
}
|
|
2507
2622
|
}
|
|
2508
2623
|
}
|
|
2509
|
-
class
|
|
2624
|
+
class Me {
|
|
2510
2625
|
constructor() {
|
|
2511
2626
|
o(this, "pathGenerator");
|
|
2512
|
-
this.pathGenerator = new
|
|
2627
|
+
this.pathGenerator = new Ae();
|
|
2513
2628
|
}
|
|
2514
2629
|
/**
|
|
2515
2630
|
* Generates the SVG header with metadata
|
|
@@ -2689,7 +2804,7 @@ class Y {
|
|
|
2689
2804
|
o(this, "dataExtractor");
|
|
2690
2805
|
o(this, "contentGenerator");
|
|
2691
2806
|
o(this, "fileHandler");
|
|
2692
|
-
this.dataExtractor = new
|
|
2807
|
+
this.dataExtractor = new De(), this.contentGenerator = new Me(), this.fileHandler = new Ie();
|
|
2693
2808
|
}
|
|
2694
2809
|
/**
|
|
2695
2810
|
* Applies default values to SVG export options
|
|
@@ -2930,12 +3045,12 @@ const q = {
|
|
|
2930
3045
|
png: "image/png",
|
|
2931
3046
|
jpg: "image/jpeg",
|
|
2932
3047
|
webp: "image/webp"
|
|
2933
|
-
},
|
|
3048
|
+
}, z = {
|
|
2934
3049
|
png: ".png",
|
|
2935
3050
|
jpg: ".jpg",
|
|
2936
3051
|
webp: ".webp"
|
|
2937
3052
|
};
|
|
2938
|
-
class
|
|
3053
|
+
class ze extends N {
|
|
2939
3054
|
/**
|
|
2940
3055
|
* Saves image content as a downloadable file
|
|
2941
3056
|
* @param content The image content (data URL or blob)
|
|
@@ -2944,7 +3059,7 @@ class $e extends N {
|
|
|
2944
3059
|
*/
|
|
2945
3060
|
saveImage(e, t, r) {
|
|
2946
3061
|
try {
|
|
2947
|
-
const i =
|
|
3062
|
+
const i = z[r];
|
|
2948
3063
|
typeof e == "string" ? this.saveImageFromDataURL(e, this.sanitizeFilename(t) + i) : this.saveImageFromBlob(e, this.sanitizeFilename(t) + i);
|
|
2949
3064
|
} catch (i) {
|
|
2950
3065
|
throw console.error(`Failed to save ${r.toUpperCase()} image:`, i), new Error(`Image save failed: ${i instanceof Error ? i.message : "Unknown error"}`);
|
|
@@ -2979,7 +3094,7 @@ class $e extends N {
|
|
|
2979
3094
|
* @returns True if the format is supported for saving
|
|
2980
3095
|
*/
|
|
2981
3096
|
validateSaveSupport(e) {
|
|
2982
|
-
return e in q && e in
|
|
3097
|
+
return e in q && e in z;
|
|
2983
3098
|
}
|
|
2984
3099
|
/**
|
|
2985
3100
|
* Gets the MIME type for the specified image format
|
|
@@ -2995,15 +3110,15 @@ class $e extends N {
|
|
|
2995
3110
|
* @returns The file extension (including the dot)
|
|
2996
3111
|
*/
|
|
2997
3112
|
getFileExtension(e) {
|
|
2998
|
-
return
|
|
3113
|
+
return z[e];
|
|
2999
3114
|
}
|
|
3000
3115
|
}
|
|
3001
|
-
class
|
|
3116
|
+
class $e {
|
|
3002
3117
|
constructor() {
|
|
3003
3118
|
o(this, "dataExtractor");
|
|
3004
3119
|
o(this, "contentGenerator");
|
|
3005
3120
|
o(this, "fileHandler");
|
|
3006
|
-
this.dataExtractor = new Ve(), this.contentGenerator = new ke(), this.fileHandler = new
|
|
3121
|
+
this.dataExtractor = new Ve(), this.contentGenerator = new ke(), this.fileHandler = new ze();
|
|
3007
3122
|
}
|
|
3008
3123
|
/**
|
|
3009
3124
|
* Applies default values to image export options
|
|
@@ -3117,6 +3232,9 @@ class I {
|
|
|
3117
3232
|
});
|
|
3118
3233
|
o(this, "_resizedCallback", () => {
|
|
3119
3234
|
});
|
|
3235
|
+
// Destroy state
|
|
3236
|
+
o(this, "_isDestroyed", !1);
|
|
3237
|
+
o(this, "_windowResizeListener", null);
|
|
3120
3238
|
this.captureSource = e, this._standalone = e === null, this._mode = t.renderMode ?? "auto", this._frameRateLimit = t.frameRate ?? 60, this.frameInterval = 1e3 / this._frameRateLimit;
|
|
3121
3239
|
}
|
|
3122
3240
|
/**
|
|
@@ -3127,16 +3245,16 @@ class I {
|
|
|
3127
3245
|
*/
|
|
3128
3246
|
static async create(e = null, t = {}) {
|
|
3129
3247
|
const r = new I(e, t), i = r._standalone ? t : void 0;
|
|
3130
|
-
r.textmodeCanvas = new
|
|
3248
|
+
r.textmodeCanvas = new be(r.captureSource, r._standalone, i), r._renderer = new fe(r.textmodeCanvas.getWebGLContext());
|
|
3131
3249
|
let s, a;
|
|
3132
3250
|
r._standalone ? (s = t.width || 800, a = t.height || 600) : (s = r.textmodeCanvas.width || 800, a = r.textmodeCanvas.height || 600), r._canvasFramebuffer = r._renderer.createFramebuffer(s, a), r._font = new xe(r._renderer, t.fontSize ?? 16), await r._font.initialize(t.fontSource);
|
|
3133
3251
|
const n = r._font.maxGlyphDimensions;
|
|
3134
3252
|
return r._grid = new ve(r.textmodeCanvas.canvas, n.width, n.height), r._pipeline = new Ue(r._renderer, r._font, r._grid), r.setupEventListeners(), r.startAutoRendering(), r;
|
|
3135
3253
|
}
|
|
3136
3254
|
setupEventListeners() {
|
|
3137
|
-
|
|
3255
|
+
this._windowResizeListener = () => {
|
|
3138
3256
|
this._standalone ? this._resizedCallback() : this.resize();
|
|
3139
|
-
}), window.ResizeObserver && this.captureSource && !this._standalone && (this.resizeObserver = new ResizeObserver(() => {
|
|
3257
|
+
}, window.addEventListener("resize", this._windowResizeListener), window.ResizeObserver && this.captureSource && !this._standalone && (this.resizeObserver = new ResizeObserver(() => {
|
|
3140
3258
|
this.resize();
|
|
3141
3259
|
}), this.resizeObserver.observe(this.captureSource));
|
|
3142
3260
|
}
|
|
@@ -3288,7 +3406,7 @@ class I {
|
|
|
3288
3406
|
* ```
|
|
3289
3407
|
*/
|
|
3290
3408
|
async saveCanvas(e, t = "png", r = {}) {
|
|
3291
|
-
await new
|
|
3409
|
+
await new $e().saveImage(this.textmodeCanvas, {
|
|
3292
3410
|
...r,
|
|
3293
3411
|
filename: e,
|
|
3294
3412
|
format: t
|
|
@@ -3358,7 +3476,19 @@ class I {
|
|
|
3358
3476
|
* ```
|
|
3359
3477
|
*/
|
|
3360
3478
|
render() {
|
|
3361
|
-
|
|
3479
|
+
if (this._isDestroyed) {
|
|
3480
|
+
console.warn("Cannot render: Textmodifier instance has been destroyed");
|
|
3481
|
+
return;
|
|
3482
|
+
}
|
|
3483
|
+
if (this.measureFrameRate(), this._frameCount++, !this._canvasFramebuffer || !this._renderer || !this._pipeline) {
|
|
3484
|
+
console.warn("Cannot render: Required resources have been disposed");
|
|
3485
|
+
return;
|
|
3486
|
+
}
|
|
3487
|
+
if (this._standalone ? this._canvasFramebuffer && (this._canvasFramebuffer.begin(), this._drawCallback(), this._renderer && this._renderer.reset(), this._canvasFramebuffer && this._canvasFramebuffer.end()) : this.captureSource && this._canvasFramebuffer && this._canvasFramebuffer.update(this.captureSource), !this._pipeline || !this._renderer) {
|
|
3488
|
+
console.warn("Cannot complete render: Pipeline or renderer has been disposed");
|
|
3489
|
+
return;
|
|
3490
|
+
}
|
|
3491
|
+
this._pipeline.render(this._canvasFramebuffer), this._pipeline.hasEnabledConverters() ? this._renderer && this._pipeline.texture && this._grid && (this._renderer.background(0), this._renderer.image(this._pipeline.texture, this._grid.offsetX, this._grid.offsetY, this._pipeline.texture.width, this._pipeline.texture.height)) : this._renderer && this._canvasFramebuffer && this._grid && (this._renderer.clear(), this._renderer.image(this._canvasFramebuffer, this._grid.offsetX, this._grid.offsetY, this._canvasFramebuffer.width, this._canvasFramebuffer.height));
|
|
3362
3492
|
}
|
|
3363
3493
|
resize() {
|
|
3364
3494
|
this.textmodeCanvas.resize(), this._canvasFramebuffer.resize(this.textmodeCanvas.width, this.textmodeCanvas.height), this._grid.resize(), this._pipeline.resize(), this._renderer.resetViewport(), this._mode !== "manual" && this.render();
|
|
@@ -3367,11 +3497,13 @@ class I {
|
|
|
3367
3497
|
* Start automatic rendering
|
|
3368
3498
|
*/
|
|
3369
3499
|
startAutoRendering() {
|
|
3370
|
-
if (this._mode !== "auto") return;
|
|
3500
|
+
if (this._mode !== "auto" || this._isDestroyed) return;
|
|
3371
3501
|
this.lastFrameTime = performance.now();
|
|
3372
3502
|
const e = (t) => {
|
|
3503
|
+
if (this._isDestroyed)
|
|
3504
|
+
return;
|
|
3373
3505
|
const r = t - this.lastFrameTime;
|
|
3374
|
-
r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), this.animationFrameId = requestAnimationFrame(e);
|
|
3506
|
+
r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), this._isDestroyed || (this.animationFrameId = requestAnimationFrame(e));
|
|
3375
3507
|
};
|
|
3376
3508
|
this.animationFrameId = requestAnimationFrame(e);
|
|
3377
3509
|
}
|
|
@@ -3380,6 +3512,7 @@ class I {
|
|
|
3380
3512
|
* Uses a rolling average for smoother frame rate reporting
|
|
3381
3513
|
*/
|
|
3382
3514
|
measureFrameRate() {
|
|
3515
|
+
if (this._isDestroyed) return;
|
|
3383
3516
|
const e = performance.now();
|
|
3384
3517
|
if (this.lastRenderTime > 0) {
|
|
3385
3518
|
const t = e - this.lastRenderTime;
|
|
@@ -3420,6 +3553,10 @@ class I {
|
|
|
3420
3553
|
* ```
|
|
3421
3554
|
*/
|
|
3422
3555
|
renderMode(e) {
|
|
3556
|
+
if (this._isDestroyed) {
|
|
3557
|
+
console.warn("Cannot change render mode: Textmodifier instance has been destroyed");
|
|
3558
|
+
return;
|
|
3559
|
+
}
|
|
3423
3560
|
this._mode !== e && (this.stopAutoRendering(), this._mode = e, e === "auto" && this.startAutoRendering());
|
|
3424
3561
|
}
|
|
3425
3562
|
/**
|
|
@@ -3973,33 +4110,77 @@ class I {
|
|
|
3973
4110
|
setUniform(e, t) {
|
|
3974
4111
|
this._renderer.setUniform(e, t);
|
|
3975
4112
|
}
|
|
4113
|
+
/**
|
|
4114
|
+
* Completely destroy this Textmodifier instance and free all associated resources.
|
|
4115
|
+
*
|
|
4116
|
+
* This method performs comprehensive cleanup of:
|
|
4117
|
+
* - WebGL resources (framebuffers, textures, shaders)
|
|
4118
|
+
* - Animation frames and timers
|
|
4119
|
+
* - Event listeners
|
|
4120
|
+
* - DOM elements
|
|
4121
|
+
* - Font resources
|
|
4122
|
+
*
|
|
4123
|
+
* After calling this method, the instance should not be used and will be eligible for garbage collection.
|
|
4124
|
+
* This method is idempotent and safe to call multiple times.
|
|
4125
|
+
*
|
|
4126
|
+
* @example
|
|
4127
|
+
* ```javascript
|
|
4128
|
+
* // Create a textmodifier instance
|
|
4129
|
+
* const textmodifier = await textmode.create(canvas);
|
|
4130
|
+
*
|
|
4131
|
+
* // Use it for rendering
|
|
4132
|
+
* textmodifier.render();
|
|
4133
|
+
*
|
|
4134
|
+
* // When done, completely clean up
|
|
4135
|
+
* textmodifier.destroy();
|
|
4136
|
+
*
|
|
4137
|
+
* // Instance is now safely disposed and ready for garbage collection
|
|
4138
|
+
* ```
|
|
4139
|
+
*/
|
|
4140
|
+
destroy() {
|
|
4141
|
+
this._isDestroyed || (this._isDestroyed = !0, this.stopAutoRendering(), this._windowResizeListener && (window.removeEventListener("resize", this._windowResizeListener), this._windowResizeListener = null), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = null), this._pipeline && !this._pipeline.isDisposed && this._pipeline.dispose(), this._font && !this._font.isDisposed && this._font.dispose(), this._grid && !this._grid.isDisposed && this._grid.dispose(), this._canvasFramebuffer && !this._canvasFramebuffer.isDisposed && this._canvasFramebuffer.dispose(), this._renderer && !this._renderer.isDisposed && this._renderer.dispose(), this.textmodeCanvas && !this.textmodeCanvas.isDisposed && this.textmodeCanvas.dispose(), this.captureSource = null, this.textmodeCanvas = null, this._renderer = null, this._canvasFramebuffer = null, this._font = null, this._grid = null, this._pipeline = null, this.resizeObserver = null, this._drawCallback = () => {
|
|
4142
|
+
}, this._resizedCallback = () => {
|
|
4143
|
+
}, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = []);
|
|
4144
|
+
}
|
|
3976
4145
|
/** Get the current grid object used for rendering. */
|
|
3977
4146
|
get grid() {
|
|
4147
|
+
if (this._isDestroyed)
|
|
4148
|
+
throw new Error("Cannot access grid: Textmodifier instance has been destroyed");
|
|
3978
4149
|
return this._grid;
|
|
3979
4150
|
}
|
|
3980
4151
|
/** Get the current font object used for rendering. */
|
|
3981
4152
|
get font() {
|
|
4153
|
+
if (this._isDestroyed)
|
|
4154
|
+
throw new Error("Cannot access font: Textmodifier instance has been destroyed");
|
|
3982
4155
|
return this._font;
|
|
3983
4156
|
}
|
|
3984
4157
|
/** Get the current rendering mode.*/
|
|
3985
4158
|
get mode() {
|
|
4159
|
+
if (this._isDestroyed)
|
|
4160
|
+
throw new Error("Cannot access mode: Textmodifier instance has been destroyed");
|
|
3986
4161
|
return this._mode;
|
|
3987
4162
|
}
|
|
3988
4163
|
/** Get the current textmode conversion pipeline. */
|
|
3989
4164
|
get pipeline() {
|
|
4165
|
+
if (this._isDestroyed)
|
|
4166
|
+
throw new Error("Cannot access pipeline: Textmodifier instance has been destroyed");
|
|
3990
4167
|
return this._pipeline;
|
|
3991
4168
|
}
|
|
3992
4169
|
/** Get the current frame count. */
|
|
3993
4170
|
get frameCount() {
|
|
3994
|
-
return this._frameCount;
|
|
4171
|
+
return this._isDestroyed ? 0 : this._frameCount;
|
|
3995
4172
|
}
|
|
3996
4173
|
/** Get the width of the canvas. */
|
|
3997
4174
|
get width() {
|
|
3998
|
-
return this.textmodeCanvas.width;
|
|
4175
|
+
return this._isDestroyed ? 0 : this.textmodeCanvas.width;
|
|
3999
4176
|
}
|
|
4000
4177
|
/** Get the height of the canvas. */
|
|
4001
4178
|
get height() {
|
|
4002
|
-
return this.textmodeCanvas.height;
|
|
4179
|
+
return this._isDestroyed ? 0 : this.textmodeCanvas.height;
|
|
4180
|
+
}
|
|
4181
|
+
/** Check if this Textmodifier instance has been destroyed. */
|
|
4182
|
+
get isDestroyed() {
|
|
4183
|
+
return this._isDestroyed;
|
|
4003
4184
|
}
|
|
4004
4185
|
}
|
|
4005
4186
|
class O {
|
|
@@ -4046,6 +4227,20 @@ class O {
|
|
|
4046
4227
|
* // Draw a rectangle with the fill color
|
|
4047
4228
|
* t.rect(x, y, 200, 150);
|
|
4048
4229
|
* });
|
|
4230
|
+
*
|
|
4231
|
+
* ////////
|
|
4232
|
+
*
|
|
4233
|
+
* // Resource management example
|
|
4234
|
+
* const textmodifier = await textmode.create(canvas);
|
|
4235
|
+
*
|
|
4236
|
+
* // Use the textmodifier...
|
|
4237
|
+
* textmodifier.render();
|
|
4238
|
+
*
|
|
4239
|
+
* // When done, completely clean up all resources
|
|
4240
|
+
* textmodifier.destroy();
|
|
4241
|
+
*
|
|
4242
|
+
* // The instance is now safely disposed and ready for garbage collection
|
|
4243
|
+
* console.log(textmodifier.isDestroyed); // true
|
|
4049
4244
|
* ```
|
|
4050
4245
|
*/
|
|
4051
4246
|
static async create(e, t = {}) {
|
|
@@ -4078,7 +4273,7 @@ class O {
|
|
|
4078
4273
|
* ```
|
|
4079
4274
|
*/
|
|
4080
4275
|
static get version() {
|
|
4081
|
-
return "0.1.
|
|
4276
|
+
return "0.1.4-beta.1";
|
|
4082
4277
|
}
|
|
4083
4278
|
constructor() {
|
|
4084
4279
|
throw new Error("Textmode is a static class and cannot be instantiated.");
|
|
@@ -4088,7 +4283,7 @@ const He = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
|
4088
4283
|
__proto__: null
|
|
4089
4284
|
}, Symbol.toStringTag, { value: "Module" })), Ne = O.create, Oe = O.setErrorLevel, We = O.version;
|
|
4090
4285
|
export {
|
|
4091
|
-
|
|
4286
|
+
be as TextmodeCanvas,
|
|
4092
4287
|
Ue as TextmodeConversionPipeline,
|
|
4093
4288
|
ne as TextmodeErrorLevel,
|
|
4094
4289
|
xe as TextmodeFont,
|