textmode.js 0.1.4-beta.2 → 0.1.4-beta.4

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.
@@ -1,6 +1,6 @@
1
1
  var se = Object.defineProperty;
2
- var ae = (h, e, t) => e in h ? se(h, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[e] = t;
3
- var o = (h, e, t) => ae(h, typeof e != "symbol" ? e + "" : e, t);
2
+ var ae = (l, e, t) => e in l ? se(l, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : l[e] = t;
3
+ var o = (l, e, t) => ae(l, typeof e != "symbol" ? e + "" : e, t);
4
4
  class F extends Error {
5
5
  constructor(t, r, i = {}) {
6
6
  const s = F.createFormattedMessage(t, i);
@@ -46,7 +46,7 @@ class F extends Error {
46
46
  return String(t);
47
47
  }
48
48
  }
49
- var ne = /* @__PURE__ */ ((h) => (h[h.SILENT = 0] = "SILENT", h[h.WARNING = 1] = "WARNING", h[h.ERROR = 2] = "ERROR", h[h.THROW = 3] = "THROW", h))(ne || {});
49
+ var ne = /* @__PURE__ */ ((l) => (l[l.SILENT = 0] = "SILENT", l[l.WARNING = 1] = "WARNING", l[l.ERROR = 2] = "ERROR", l[l.THROW = 3] = "THROW", l))(ne || {});
50
50
  const E = class E {
51
51
  constructor() {
52
52
  o(this, "_options", {
@@ -209,12 +209,6 @@ class oe {
209
209
  const { gl: e } = this;
210
210
  this._framebuffer && (e.deleteFramebuffer(this._framebuffer), this._framebuffer = null), this._texture && (e.deleteTexture(this._texture), this._texture = null), this._pixels = null;
211
211
  }
212
- /**
213
- * Check if this framebuffer has been disposed
214
- */
215
- get isDisposed() {
216
- return this._framebuffer === null || this._texture === null;
217
- }
218
212
  get framebuffer() {
219
213
  return this._framebuffer;
220
214
  }
@@ -239,7 +233,7 @@ class Q {
239
233
  this.gl = e, this.x = t, this.y = r;
240
234
  }
241
235
  }
242
- class A {
236
+ class M {
243
237
  constructor(e, t, r, i, s) {
244
238
  /** The WebGL rendering context */
245
239
  o(this, "gl");
@@ -250,12 +244,12 @@ class A {
250
244
  /** Bytes per vertex: depends on position format (vec2 vs vec3) */
251
245
  o(this, "bytesPerVertex");
252
246
  this.gl = e, this.bytesPerVertex = 16;
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;
247
+ const a = e.getParameter(e.VIEWPORT), n = a[2], h = a[3], c = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, u = t / n * 2 - 1, d = (t + i) / n * 2 - 1;
254
248
  let f, g;
255
- c ? (f = r / l * 2 - 1, g = (r + s) / l * 2 - 1) : (f = 1 - r / l * 2, g = 1 - (r + s) / l * 2);
256
- let p, _, b, C;
257
- p = u, b = d, _ = f, C = g;
258
- const v = this.generateVertices(p, _, b, C);
249
+ c ? (f = r / h * 2 - 1, g = (r + s) / h * 2 - 1) : (f = 1 - r / h * 2, g = 1 - (r + s) / h * 2);
250
+ let _, p, b, C;
251
+ _ = u, b = d, p = f, C = g;
252
+ const v = this.generateVertices(_, p, b, C);
259
253
  this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, v, e.STATIC_DRAW);
260
254
  }
261
255
  /**
@@ -306,7 +300,7 @@ class A {
306
300
  this.gl.enableVertexAttribArray(t), this.gl.vertexAttribPointer(t, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 0), this.gl.enableVertexAttribArray(r), this.gl.vertexAttribPointer(r, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 8), this.gl.drawArrays(this.gl.TRIANGLES, 0, this.vertexCount), this.gl.disableVertexAttribArray(t), this.gl.disableVertexAttribArray(r);
307
301
  }
308
302
  }
309
- class he extends Q {
303
+ class le extends Q {
310
304
  constructor(t, r, i, s, a) {
311
305
  super(t, r, i);
312
306
  o(this, "width");
@@ -317,7 +311,7 @@ class he extends Q {
317
311
  * Render the filled rectangle using the existing Rectangle geometry.
318
312
  */
319
313
  renderFill() {
320
- new A(this.gl, this.x, this.y, this.width, this.height).render();
314
+ new M(this.gl, this.x, this.y, this.width, this.height).render();
321
315
  }
322
316
  /**
323
317
  * Render the stroke rectangle as four separate Rectangle instances for each edge.
@@ -326,11 +320,11 @@ class he extends Q {
326
320
  */
327
321
  renderStroke(t) {
328
322
  if (t <= 0) return;
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);
323
+ const r = new M(this.gl, this.x, this.y, this.width, t), i = new M(this.gl, this.x + this.width - t, this.y, t, this.height), s = new M(this.gl, this.x, this.y + this.height - t, this.width, t), a = new M(this.gl, this.x, this.y, t, this.height);
330
324
  r.render(), i.render(), s.render(), a.render();
331
325
  }
332
326
  }
333
- class le {
327
+ class he {
334
328
  constructor(e, t, r, i, s, a) {
335
329
  /** The WebGL rendering context */
336
330
  o(this, "gl");
@@ -341,15 +335,15 @@ class le {
341
335
  /** Bytes per vertex: vec2+vec2 = 16 bytes */
342
336
  o(this, "bytesPerVertex");
343
337
  this.gl = e, this.bytesPerVertex = 16;
344
- const n = e.getParameter(e.VIEWPORT), l = n[2], c = n[3], u = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, d = i - t, f = s - r, g = Math.sqrt(d * d + f * f);
338
+ const n = e.getParameter(e.VIEWPORT), h = n[2], c = n[3], u = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, d = i - t, f = s - r, g = Math.sqrt(d * d + f * f);
345
339
  if (g === 0) {
346
340
  const ie = this.generateVertices(0, 0, 0, 0);
347
341
  this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, ie, e.STATIC_DRAW);
348
342
  return;
349
343
  }
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;
344
+ const _ = d / g, b = -(f / g), C = _, v = a / 2, w = t + b * v, A = r + C * v, R = t - b * v, y = r - C * v, P = i + b * v, D = s + C * v, Z = i - b * v, W = s - C * v, J = w / h * 2 - 1, K = R / h * 2 - 1, ee = P / h * 2 - 1, te = Z / h * 2 - 1;
351
345
  let B, G, V, k;
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);
346
+ u ? (B = A / c * 2 - 1, G = y / c * 2 - 1, V = D / c * 2 - 1, k = W / c * 2 - 1) : (B = 1 - A / c * 2, G = 1 - y / c * 2, V = 1 - D / c * 2, k = 1 - W / c * 2);
353
347
  const re = this.generateLineVertices(
354
348
  J,
355
349
  B,
@@ -405,7 +399,7 @@ class le {
405
399
  * Uses the four corners calculated based on line direction and thickness
406
400
  * @private
407
401
  */
408
- generateLineVertices(e, t, r, i, s, a, n, l) {
402
+ generateLineVertices(e, t, r, i, s, a, n, h) {
409
403
  return new Float32Array([
410
404
  e,
411
405
  t,
@@ -428,7 +422,7 @@ class le {
428
422
  1,
429
423
  // corner2 (start - perpendicular)
430
424
  n,
431
- l,
425
+ h,
432
426
  1,
433
427
  1,
434
428
  // corner4 (end - perpendicular)
@@ -468,7 +462,7 @@ class ce extends Q {
468
462
  */
469
463
  renderStroke(t) {
470
464
  if (t <= 0) return;
471
- new le(this.gl, this.x, this.y, this.x2, this.y2, t).render();
465
+ new he(this.gl, this.x, this.y, this.x2, this.y2, t).render();
472
466
  }
473
467
  }
474
468
  class T {
@@ -611,12 +605,6 @@ class T {
611
605
  dispose() {
612
606
  this.program && (this.gl.deleteProgram(this.program), this.program = null), this.uniformLocations.clear(), this.attributeLocations.clear(), this.textureUnitCounter = 0;
613
607
  }
614
- /**
615
- * Check if this shader has been disposed
616
- */
617
- get isDisposed() {
618
- return this.program === null;
619
- }
620
608
  /**
621
609
  * Reset texture unit counter (useful when starting a new frame)
622
610
  */
@@ -756,18 +744,18 @@ class fe {
756
744
  * Draw a rectangle with the current fill and/or stroke settings
757
745
  */
758
746
  rect(e, t, r, i) {
759
- const s = new he(this.gl, e, t, r, i);
747
+ const s = new le(this.gl, e, t, r, i);
760
748
  if (this.currentShader !== null) {
761
749
  if (this.currentRotation !== 0) {
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);
750
+ const { centerX: d, centerY: f, radians: g, aspectRatio: _ } = this.calculateRotationParams(e, t, r, i);
751
+ this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", _);
764
752
  } else
765
753
  this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
766
754
  s.renderFill(), this.currentShader = null;
767
755
  return;
768
756
  }
769
- const a = this.solidColorShader, { centerX: n, centerY: l, radians: c, aspectRatio: u } = this.calculateRotationParams(e, t, r, i);
770
- this.fillMode && (this.shader(a), this.setUniform("u_color", this.currentFillColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [n, l]), this.setUniform("u_aspectRatio", u), s.renderFill()), this.strokeMode && (this.shader(a), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [n, l]), this.setUniform("u_aspectRatio", u), s.renderStroke(this.currentStrokeWeight)), this.currentShader = null;
757
+ const a = this.solidColorShader, { centerX: n, centerY: h, radians: c, aspectRatio: u } = this.calculateRotationParams(e, t, r, i);
758
+ this.fillMode && (this.shader(a), this.setUniform("u_color", this.currentFillColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [n, h]), this.setUniform("u_aspectRatio", u), s.renderFill()), this.strokeMode && (this.shader(a), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [n, h]), this.setUniform("u_aspectRatio", u), s.renderStroke(this.currentStrokeWeight)), this.currentShader = null;
771
759
  }
772
760
  /**
773
761
  * Draw a line from (x1, y1) to (x2, y2) with the current stroke settings.
@@ -782,25 +770,25 @@ class fe {
782
770
  const s = new ce(this.gl, e, t, r, i);
783
771
  if (this.currentShader !== null) {
784
772
  if (this.currentRotation !== 0) {
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);
773
+ const p = (e + r) / 2, b = (t + i) / 2, C = Math.abs(r - e), v = Math.abs(i - t), { centerX: w, centerY: A, radians: R, aspectRatio: y } = this.calculateRotationParams(p - C / 2, b - v / 2, C, v);
774
+ this.setUniform("u_rotation", R), this.setUniform("u_center", [w, A]), this.setUniform("u_aspectRatio", y);
787
775
  } else
788
776
  this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
789
777
  s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
790
778
  return;
791
779
  }
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;
780
+ const a = this.solidColorShader, n = (e + r) / 2, h = (t + i) / 2, c = Math.abs(r - e), u = Math.abs(i - t), { centerX: d, centerY: f, radians: g, aspectRatio: _ } = this.calculateRotationParams(n - c / 2, h - u / 2, c, u);
781
+ this.shader(a), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", _), s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
794
782
  }
795
783
  /**
796
784
  * Calculate rotation parameters for built-in shaders (NDC coordinates)
797
785
  */
798
786
  calculateRotationParams(e, t, r, i) {
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;
787
+ const s = this.gl.getParameter(this.gl.VIEWPORT), a = s[2], n = s[3], h = a / n, c = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING) !== null, u = e + r / 2, d = t + i / 2, f = u / a * 2 - 1;
800
788
  let g;
801
789
  c ? g = d / n * 2 - 1 : g = 1 - d / n * 2;
802
- const p = this.currentRotation * Math.PI / 180;
803
- return { centerX: f, centerY: g, radians: p, aspectRatio: l };
790
+ const _ = this.currentRotation * Math.PI / 180;
791
+ return { centerX: f, centerY: g, radians: _, aspectRatio: h };
804
792
  }
805
793
  /**
806
794
  * Create a new framebuffer
@@ -837,31 +825,25 @@ class fe {
837
825
  * This method is idempotent and safe to call multiple times.
838
826
  */
839
827
  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;
828
+ this.imageShader.dispose(), this.solidColorShader.dispose(), this.imageShader = null, this.solidColorShader = null, this.currentShader = null, this.stateStack = [];
847
829
  }
848
830
  /**
849
831
  * Render a framebuffer at a specific position with optional scaling
850
832
  */
851
833
  image(e, t, r, i, s) {
852
834
  this.shader(this.imageShader), this.setUniform("u_texture", e.texture);
853
- const { centerX: a, centerY: n, radians: l, aspectRatio: c } = this.calculateRotationParams(
835
+ const { centerX: a, centerY: n, radians: h, aspectRatio: c } = this.calculateRotationParams(
854
836
  t,
855
837
  r,
856
838
  i ?? e.width,
857
839
  s ?? e.height
858
840
  );
859
- this.setUniform("u_rotation", l), this.setUniform("u_center", [a, n]), this.setUniform("u_aspectRatio", c), this.rect(t, r, i ?? e.width, s ?? e.height);
841
+ this.setUniform("u_rotation", h), this.setUniform("u_center", [a, n]), this.setUniform("u_aspectRatio", c), this.rect(t, r, i ?? e.width, s ?? e.height);
860
842
  }
861
843
  }
862
844
  var m = {};
863
- m.parse = function(h) {
864
- var e = function(s, a, n, l) {
845
+ m.parse = function(l) {
846
+ var e = function(s, a, n, h) {
865
847
  var c = m.T, u = {
866
848
  cmap: c.cmap,
867
849
  head: c.head,
@@ -874,115 +856,115 @@ m.parse = function(h) {
874
856
  for (var f in u) {
875
857
  var g = m.findTable(s, f, n);
876
858
  if (g) {
877
- var p = g[0], _ = l[p];
878
- _ == null && (_ = u[f].parseTab(s, p, g[1], d)), d[f] = l[p] = _;
859
+ var _ = g[0], p = h[_];
860
+ p == null && (p = u[f].parseTab(s, _, g[1], d)), d[f] = h[_] = p;
879
861
  }
880
862
  }
881
863
  return d;
882
- }, t = new Uint8Array(h), r = {}, i = e(t, 0, 0, r);
864
+ }, t = new Uint8Array(l), r = {}, i = e(t, 0, 0, r);
883
865
  return [i];
884
866
  };
885
- m.findTable = function(h, e, t) {
886
- for (var r = m.B, i = r.readUshort(h, t + 4), s = t + 12, a = 0; a < i; a++) {
887
- var n = r.readASCII(h, s, 4);
888
- r.readUint(h, s + 4);
889
- var l = r.readUint(h, s + 8), c = r.readUint(h, s + 12);
890
- if (n == e) return [l, c];
867
+ m.findTable = function(l, e, t) {
868
+ for (var r = m.B, i = r.readUshort(l, t + 4), s = t + 12, a = 0; a < i; a++) {
869
+ var n = r.readASCII(l, s, 4);
870
+ r.readUint(l, s + 4);
871
+ var h = r.readUint(l, s + 8), c = r.readUint(l, s + 12);
872
+ if (n == e) return [h, c];
891
873
  s += 16;
892
874
  }
893
875
  return null;
894
876
  };
895
877
  m.T = {};
896
878
  m.B = {
897
- readShort: function(h, e) {
879
+ readShort: function(l, e) {
898
880
  var t = m.B.t.uint16;
899
- return t[0] = h[e] << 8 | h[e + 1], m.B.t.int16[0];
881
+ return t[0] = l[e] << 8 | l[e + 1], m.B.t.int16[0];
900
882
  },
901
- readUshort: function(h, e) {
902
- return h[e] << 8 | h[e + 1];
883
+ readUshort: function(l, e) {
884
+ return l[e] << 8 | l[e + 1];
903
885
  },
904
- readUshorts: function(h, e, t) {
886
+ readUshorts: function(l, e, t) {
905
887
  for (var r = [], i = 0; i < t; i++)
906
- r.push(m.B.readUshort(h, e + i * 2));
888
+ r.push(m.B.readUshort(l, e + i * 2));
907
889
  return r;
908
890
  },
909
- readUint: function(h, e) {
891
+ readUint: function(l, e) {
910
892
  var t = m.B.t.uint8;
911
- return t[3] = h[e], t[2] = h[e + 1], t[1] = h[e + 2], t[0] = h[e + 3], m.B.t.uint32[0];
893
+ return t[3] = l[e], t[2] = l[e + 1], t[1] = l[e + 2], t[0] = l[e + 3], m.B.t.uint32[0];
912
894
  },
913
- readASCII: function(h, e, t) {
914
- for (var r = "", i = 0; i < t; i++) r += String.fromCharCode(h[e + i]);
895
+ readASCII: function(l, e, t) {
896
+ for (var r = "", i = 0; i < t; i++) r += String.fromCharCode(l[e + i]);
915
897
  return r;
916
898
  },
917
899
  // Simplified typed array buffer - only what's needed
918
900
  t: function() {
919
- var h = new ArrayBuffer(8);
901
+ var l = new ArrayBuffer(8);
920
902
  return {
921
- uint8: new Uint8Array(h),
922
- int16: new Int16Array(h),
923
- uint16: new Uint16Array(h),
924
- uint32: new Uint32Array(h)
903
+ uint8: new Uint8Array(l),
904
+ int16: new Int16Array(l),
905
+ uint16: new Uint16Array(l),
906
+ uint32: new Uint32Array(l)
925
907
  };
926
908
  }()
927
909
  };
928
910
  m.T.cmap = {
929
- parseTab: function(h, e, t) {
911
+ parseTab: function(l, e, t) {
930
912
  var r = { tables: [], ids: {}, off: e };
931
- h = new Uint8Array(h.buffer, e, t), e = 0;
913
+ l = new Uint8Array(l.buffer, e, t), e = 0;
932
914
  var i = m.B, s = i.readUshort, a = m.T.cmap;
933
- s(h, e), e += 2;
934
- var n = s(h, e);
915
+ s(l, e), e += 2;
916
+ var n = s(l, e);
935
917
  e += 2;
936
- for (var l = [], c = 0; c < n; c++) {
937
- var u = s(h, e);
918
+ for (var h = [], c = 0; c < n; c++) {
919
+ var u = s(l, e);
938
920
  e += 2;
939
- var d = s(h, e);
921
+ var d = s(l, e);
940
922
  e += 2;
941
- var f = i.readUint(h, e);
923
+ var f = i.readUint(l, e);
942
924
  e += 4;
943
- var g = "p" + u + "e" + d, p = l.indexOf(f);
944
- if (p == -1) {
945
- p = r.tables.length;
946
- var _ = {};
947
- l.push(f);
948
- var b = _.format = s(h, f);
949
- b == 4 ? _ = a.parse4(h, f, _) : b == 12 && (_ = a.parse12(h, f, _)), r.tables.push(_);
925
+ var g = "p" + u + "e" + d, _ = h.indexOf(f);
926
+ if (_ == -1) {
927
+ _ = r.tables.length;
928
+ var p = {};
929
+ h.push(f);
930
+ var b = p.format = s(l, f);
931
+ b == 4 ? p = a.parse4(l, f, p) : b == 12 && (p = a.parse12(l, f, p)), r.tables.push(p);
950
932
  }
951
- r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] = p;
933
+ r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] = _;
952
934
  }
953
935
  return r;
954
936
  },
955
- parse4: function(h, e, t) {
937
+ parse4: function(l, e, t) {
956
938
  var r = m.B, i = r.readUshort, s = r.readUshorts, a = e;
957
939
  e += 2;
958
- var n = i(h, e);
959
- e += 2, i(h, e), e += 2;
960
- var l = i(h, e);
940
+ var n = i(l, e);
941
+ e += 2, i(l, e), e += 2;
942
+ var h = i(l, e);
961
943
  e += 2;
962
- var c = l >>> 1;
963
- t.searchRange = i(h, e), e += 2, t.entrySelector = i(h, e), e += 2, t.rangeShift = i(h, e), e += 2, t.endCount = s(h, e, c), e += c * 2, e += 2, t.startCount = s(h, e, c), e += c * 2, t.idDelta = [];
944
+ var c = h >>> 1;
945
+ t.searchRange = i(l, e), e += 2, t.entrySelector = i(l, e), e += 2, t.rangeShift = i(l, e), e += 2, t.endCount = s(l, e, c), e += c * 2, e += 2, t.startCount = s(l, e, c), e += c * 2, t.idDelta = [];
964
946
  for (var u = 0; u < c; u++)
965
- t.idDelta.push(r.readShort(h, e)), e += 2;
966
- return t.idRangeOffset = s(h, e, c), e += c * 2, t.glyphIdArray = s(h, e, a + n - e >> 1), t;
947
+ t.idDelta.push(r.readShort(l, e)), e += 2;
948
+ return t.idRangeOffset = s(l, e, c), e += c * 2, t.glyphIdArray = s(l, e, a + n - e >> 1), t;
967
949
  },
968
- parse12: function(h, e, t) {
950
+ parse12: function(l, e, t) {
969
951
  var r = m.B, i = r.readUint;
970
- e += 4, i(h, e), e += 4, i(h, e), e += 4;
971
- var s = i(h, e) * 3;
952
+ e += 4, i(l, e), e += 4, i(l, e), e += 4;
953
+ var s = i(l, e) * 3;
972
954
  e += 4;
973
955
  for (var a = t.groups = new Uint32Array(s), n = 0; n < s; n += 3)
974
- a[n] = i(h, e + (n << 2)), a[n + 1] = i(h, e + (n << 2) + 4), a[n + 2] = i(h, e + (n << 2) + 8);
956
+ a[n] = i(l, e + (n << 2)), a[n + 1] = i(l, e + (n << 2) + 4), a[n + 2] = i(l, e + (n << 2) + 8);
975
957
  return t;
976
958
  }
977
959
  };
978
960
  m.T.head = {
979
- parseTab: function(h, e, t) {
961
+ parseTab: function(l, e, t) {
980
962
  var r = m.B, i = {};
981
- return e += 18, i.unitsPerEm = r.readUshort(h, e), e += 2, e += 16, i.xMin = r.readShort(h, e), e += 2, i.yMin = r.readShort(h, e), e += 2, i.xMax = r.readShort(h, e), e += 2, i.yMax = r.readShort(h, e), e += 2, e += 6, i.indexToLocFormat = r.readShort(h, e), i;
963
+ return e += 18, i.unitsPerEm = r.readUshort(l, e), e += 2, e += 16, i.xMin = r.readShort(l, e), e += 2, i.yMin = r.readShort(l, e), e += 2, i.xMax = r.readShort(l, e), e += 2, i.yMax = r.readShort(l, e), e += 2, e += 6, i.indexToLocFormat = r.readShort(l, e), i;
982
964
  }
983
965
  };
984
966
  m.T.hhea = {
985
- parseTab: function(h, e, t) {
967
+ parseTab: function(l, e, t) {
986
968
  var r = m.B, i = {};
987
969
  e += 4;
988
970
  for (var s = [
@@ -1003,52 +985,52 @@ m.T.hhea = {
1003
985
  "metricDataFormat",
1004
986
  "numberOfHMetrics"
1005
987
  ], a = 0; a < s.length; a++) {
1006
- var n = s[a], l = n == "advanceWidthMax" || n == "numberOfHMetrics" ? r.readUshort : r.readShort;
1007
- i[n] = l(h, e + a * 2);
988
+ var n = s[a], h = n == "advanceWidthMax" || n == "numberOfHMetrics" ? r.readUshort : r.readShort;
989
+ i[n] = h(l, e + a * 2);
1008
990
  }
1009
991
  return i;
1010
992
  }
1011
993
  };
1012
994
  m.T.hmtx = {
1013
- parseTab: function(h, e, t, r) {
1014
- for (var i = m.B, s = [], a = [], n = r.maxp.numGlyphs, l = r.hhea.numberOfHMetrics, c = 0, u = 0, d = 0; d < l; )
1015
- c = i.readUshort(h, e + (d << 2)), u = i.readShort(h, e + (d << 2) + 2), s.push(c), a.push(u), d++;
995
+ parseTab: function(l, e, t, r) {
996
+ for (var i = m.B, s = [], a = [], n = r.maxp.numGlyphs, h = r.hhea.numberOfHMetrics, c = 0, u = 0, d = 0; d < h; )
997
+ c = i.readUshort(l, e + (d << 2)), u = i.readShort(l, e + (d << 2) + 2), s.push(c), a.push(u), d++;
1016
998
  for (; d < n; )
1017
999
  s.push(c), a.push(u), d++;
1018
1000
  return { aWidth: s, lsBearing: a };
1019
1001
  }
1020
1002
  };
1021
1003
  m.T.maxp = {
1022
- parseTab: function(h, e, t) {
1004
+ parseTab: function(l, e, t) {
1023
1005
  var r = m.B, i = r.readUshort, s = {};
1024
- return r.readUint(h, e), e += 4, s.numGlyphs = i(h, e), e += 2, s;
1006
+ return r.readUint(l, e), e += 4, s.numGlyphs = i(l, e), e += 2, s;
1025
1007
  }
1026
1008
  };
1027
1009
  m.T.loca = {
1028
- parseTab: function(h, e, t, r) {
1010
+ parseTab: function(l, e, t, r) {
1029
1011
  var i = m.B, s = [], a = r.head.indexToLocFormat, n = r.maxp.numGlyphs + 1;
1030
- if (a == 0) for (var l = 0; l < n; l++) s.push(i.readUshort(h, e + (l << 1)) << 1);
1031
- if (a == 1) for (var l = 0; l < n; l++) s.push(i.readUint(h, e + (l << 2)));
1012
+ if (a == 0) for (var h = 0; h < n; h++) s.push(i.readUshort(l, e + (h << 1)) << 1);
1013
+ if (a == 1) for (var h = 0; h < n; h++) s.push(i.readUint(l, e + (h << 2)));
1032
1014
  return s;
1033
1015
  }
1034
1016
  };
1035
1017
  m.T.glyf = {
1036
- parseTab: function(h, e, t, r) {
1018
+ parseTab: function(l, e, t, r) {
1037
1019
  for (var i = [], s = r.maxp.numGlyphs, a = 0; a < s; a++) i.push(null);
1038
1020
  return i;
1039
1021
  },
1040
- _parseGlyf: function(h, e) {
1041
- var t = m.B, r = h._data, i = h.loca;
1022
+ _parseGlyf: function(l, e) {
1023
+ var t = m.B, r = l._data, i = l.loca;
1042
1024
  if (i[e] == i[e + 1]) return null;
1043
- var s = m.findTable(r, "glyf", h._offset)[0] + i[e], a = {};
1025
+ var s = m.findTable(r, "glyf", l._offset)[0] + i[e], a = {};
1044
1026
  if (a.noc = t.readShort(r, s), s += 2, a.xMin = t.readShort(r, s), s += 2, a.yMin = t.readShort(r, s), s += 2, a.xMax = t.readShort(r, s), s += 2, a.yMax = t.readShort(r, s), s += 2, a.xMin >= a.xMax || a.yMin >= a.yMax) return null;
1045
1027
  if (a.noc > 0) {
1046
1028
  a.endPts = [];
1047
1029
  for (var n = 0; n < a.noc; n++)
1048
1030
  a.endPts.push(t.readUshort(r, s)), s += 2;
1049
- var l = t.readUshort(r, s);
1050
- if (s += 2, r.length - s < l) return null;
1051
- s += l;
1031
+ var h = t.readUshort(r, s);
1032
+ if (s += 2, r.length - s < h) return null;
1033
+ s += h;
1052
1034
  var c = a.endPts[a.noc - 1] + 1;
1053
1035
  a.flags = [];
1054
1036
  for (var n = 0; n < c; n++) {
@@ -1062,16 +1044,16 @@ m.T.glyf = {
1062
1044
  }
1063
1045
  a.xs = [];
1064
1046
  for (var n = 0; n < c; n++) {
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);
1047
+ var g = (a.flags[n] & 2) != 0, _ = (a.flags[n] & 16) != 0;
1048
+ g ? (a.xs.push(_ ? r[s] : -r[s]), s++) : _ ? a.xs.push(0) : (a.xs.push(t.readShort(r, s)), s += 2);
1067
1049
  }
1068
1050
  a.ys = [];
1069
1051
  for (var n = 0; n < c; n++) {
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);
1052
+ var g = (a.flags[n] & 4) != 0, _ = (a.flags[n] & 32) != 0;
1053
+ g ? (a.ys.push(_ ? r[s] : -r[s]), s++) : _ ? a.ys.push(0) : (a.ys.push(t.readShort(r, s)), s += 2);
1072
1054
  }
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;
1055
+ for (var p = 0, b = 0, n = 0; n < c; n++)
1056
+ p += a.xs[n], b += a.ys[n], a.xs[n] = p, a.ys[n] = b;
1075
1057
  } else
1076
1058
  a.parts = [];
1077
1059
  return a;
@@ -1111,8 +1093,8 @@ class me {
1111
1093
  if (!(i === 65535 && s === 65535)) {
1112
1094
  for (let a = i; a <= s; a++)
1113
1095
  if (this._calculateGlyphIndexFormat4(e, a, r) > 0) {
1114
- const l = String.fromCodePoint(a);
1115
- t.push(l);
1096
+ const h = String.fromCodePoint(a);
1097
+ t.push(h);
1116
1098
  }
1117
1099
  }
1118
1100
  }
@@ -1195,9 +1177,9 @@ class ge {
1195
1177
  * @returns Object containing framebuffer, columns, and rows
1196
1178
  */
1197
1179
  createTextureAtlas(e, t, r, i) {
1198
- const s = e.length, a = Math.ceil(Math.sqrt(s)), n = Math.ceil(s / a), l = t.width * a, c = t.height * n;
1199
- this._setupCanvas(l, c, r, i), this._renderCharactersToCanvas(e, t, a, r), this._applyBlackWhiteThreshold();
1200
- const u = this._renderer.createFramebuffer(l, c, { filter: "nearest" });
1180
+ const s = e.length, a = Math.ceil(Math.sqrt(s)), n = Math.ceil(s / a), h = t.width * a, c = t.height * n;
1181
+ this._setupCanvas(h, c, r, i), this._renderCharactersToCanvas(e, t, a, r), this._applyBlackWhiteThreshold();
1182
+ const u = this._renderer.createFramebuffer(h, c, { filter: "nearest" });
1201
1183
  return u.update(this._textureCanvas), {
1202
1184
  framebuffer: u,
1203
1185
  columns: a,
@@ -1225,7 +1207,7 @@ class ge {
1225
1207
  */
1226
1208
  _renderCharactersToCanvas(e, t, r, i) {
1227
1209
  for (let s = 0; s < e.length; s++) {
1228
- const a = s % r, n = Math.floor(s / r), l = a * t.width + t.width * 0.5, c = n * t.height + t.height * 0.5, u = Math.round(l - t.width * 0.5), d = Math.round(c - i * 0.5);
1210
+ const a = s % r, n = Math.floor(s / r), h = a * t.width + t.width * 0.5, c = n * t.height + t.height * 0.5, u = Math.round(h - t.width * 0.5), d = Math.round(c - i * 0.5);
1229
1211
  this._textureContext.fillText(e[s].character, u, d);
1230
1212
  }
1231
1213
  }
@@ -1244,7 +1226,7 @@ class ge {
1244
1226
  this._textureContext.putImageData(t, 0, 0);
1245
1227
  }
1246
1228
  }
1247
- class _e {
1229
+ class pe {
1248
1230
  /**
1249
1231
  * Creates a new MetricsCalculation instance.
1250
1232
  */
@@ -1265,8 +1247,8 @@ class _e {
1265
1247
  this._tempContext.font = `${t}px ${r}`;
1266
1248
  let i = 0, s = 0;
1267
1249
  for (const a of e) {
1268
- const n = this._tempContext.measureText(a), l = n.width, c = n.actualBoundingBoxAscent + n.actualBoundingBoxDescent;
1269
- l > 0 && (i = Math.max(i, l), s = Math.max(s, c));
1250
+ const n = this._tempContext.measureText(a), h = n.width, c = n.actualBoundingBoxAscent + n.actualBoundingBoxDescent;
1251
+ h > 0 && (i = Math.max(i, h), s = Math.max(s, c));
1270
1252
  }
1271
1253
  return {
1272
1254
  width: Math.ceil(i),
@@ -1274,7 +1256,7 @@ class _e {
1274
1256
  };
1275
1257
  }
1276
1258
  }
1277
- class pe {
1259
+ class _e {
1278
1260
  /**
1279
1261
  * Creates TextmodeCharacter objects with unique color assignments.
1280
1262
  * @param characters Array of character strings
@@ -1286,8 +1268,8 @@ class pe {
1286
1268
  const s = r.codePointAt(0) || 0, a = this._generateCharacterColor(i);
1287
1269
  let n = 0;
1288
1270
  if (t.hmtx && t.hmtx.aWidth) {
1289
- const l = this._getGlyphIndex(t, s);
1290
- l > 0 && t.hmtx.aWidth[l] !== void 0 && (n = t.hmtx.aWidth[l]);
1271
+ const h = this._getGlyphIndex(t, s);
1272
+ h > 0 && t.hmtx.aWidth[h] !== void 0 && (n = t.hmtx.aWidth[h]);
1291
1273
  }
1292
1274
  return {
1293
1275
  character: r,
@@ -1386,7 +1368,7 @@ class xe {
1386
1368
  o(this, "_textureAtlas");
1387
1369
  o(this, "_metricsCalculator");
1388
1370
  o(this, "_characterColorMapper");
1389
- this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new _e(), this._characterColorMapper = new pe();
1371
+ this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new pe(), this._characterColorMapper = new _e();
1390
1372
  }
1391
1373
  /**
1392
1374
  * Initializes the font manager by loading the font and creating the texture atlas.
@@ -1529,13 +1511,7 @@ class xe {
1529
1511
  * This method is idempotent and safe to call multiple times.
1530
1512
  */
1531
1513
  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;
1514
+ this._fontFramebuffer.dispose(), 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;
1539
1515
  }
1540
1516
  /** Returns the font size used for rendering. */
1541
1517
  get fontSize() {
@@ -1658,12 +1634,6 @@ class ve {
1658
1634
  dispose() {
1659
1635
  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
1636
  }
1661
- /**
1662
- * Check if this TextmodeGrid has been disposed
1663
- */
1664
- get isDisposed() {
1665
- return this._canvas === null;
1666
- }
1667
1637
  /** Returns the number of columns in the grid. */
1668
1638
  get cols() {
1669
1639
  return this._cols;
@@ -1709,8 +1679,8 @@ class be {
1709
1679
  (a === 0 || n === 0) && u.videoWidth > 0 && u.videoHeight > 0 && (a = u.videoWidth, n = u.videoHeight);
1710
1680
  }
1711
1681
  r.width = a, r.height = n, r.style.position = "absolute", r.style.pointerEvents = "none";
1712
- const l = window.getComputedStyle(this.captureSource);
1713
- let c = parseInt(l.zIndex || "0", 10);
1682
+ const h = window.getComputedStyle(this.captureSource);
1683
+ let c = parseInt(h.zIndex || "0", 10);
1714
1684
  isNaN(c) && (c = 0), r.style.zIndex = (c + 1).toString(), this.positionOverlayCanvas(r), (i = this.captureSource.parentNode) == null || i.insertBefore(r, this.captureSource.nextSibling);
1715
1685
  }
1716
1686
  return r;
@@ -1769,12 +1739,6 @@ class be {
1769
1739
  }
1770
1740
  this.captureSource = null;
1771
1741
  }
1772
- /**
1773
- * Check if this TextmodeCanvas has been disposed
1774
- */
1775
- get isDisposed() {
1776
- return this._canvas === null;
1777
- }
1778
1742
  get canvas() {
1779
1743
  return this._canvas;
1780
1744
  }
@@ -1837,13 +1801,7 @@ class U {
1837
1801
  * This method is idempotent and safe to call multiple times.
1838
1802
  */
1839
1803
  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;
1804
+ this._characterFramebuffer.dispose(), this._primaryColorFramebuffer.dispose(), this._secondaryColorFramebuffer.dispose(), this._rotationFramebuffer.dispose(), this._transformFramebuffer.dispose(), this._characterFramebuffer = null, this._primaryColorFramebuffer = null, this._secondaryColorFramebuffer = null, this._rotationFramebuffer = null, this._transformFramebuffer = null;
1847
1805
  }
1848
1806
  /** Returns the framebuffer containing character data. */
1849
1807
  get characterFramebuffer() {
@@ -1925,7 +1883,7 @@ class Ce {
1925
1883
  return this._framebuffer.texture;
1926
1884
  }
1927
1885
  }
1928
- class X extends U {
1886
+ class H extends U {
1929
1887
  constructor(t, r, i, s = {}) {
1930
1888
  super(t, r, i, s);
1931
1889
  o(this, "palette");
@@ -1945,17 +1903,31 @@ class X extends U {
1945
1903
  /**
1946
1904
  * Sets the color of the characters affected by the converter.
1947
1905
  * This is only used when `characterColorMode` is set to `'fixed'`.
1948
- * @param r Red component (0-255).
1906
+ * @param r Red component (0-255) or hex string (e.g., '#FF0000', '#F00', 'FF0000', 'F00').
1949
1907
  * @param g Green component (0-255).
1950
1908
  * @param b Blue component (0-255).
1951
1909
  * @param a Alpha component (0-255).
1952
1910
  */
1953
- characterColor(t, r = t, i = t, s = 255) {
1954
- x.validate(
1955
- [t, r, i, s].every((a) => a >= 0 && a <= 255),
1911
+ characterColor(t, r, i, s = 255) {
1912
+ let a, n, h, c;
1913
+ if (typeof t == "string") {
1914
+ const u = this.parseHexColor(t);
1915
+ if (!u) {
1916
+ x.validate(
1917
+ !1,
1918
+ "Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
1919
+ { method: "characterColor", providedValue: t }
1920
+ );
1921
+ return;
1922
+ }
1923
+ [a, n, h, c] = u;
1924
+ } else if (a = t, n = r !== void 0 ? r : t, h = i !== void 0 ? i : t, c = s, !x.validate(
1925
+ [a, n, h, c].every((u) => u >= 0 && u <= 255),
1956
1926
  "Character color values must be between 0 and 255",
1957
- { method: "characterColor", providedValues: { r: t, g: r, b: i, a: s } }
1958
- ) && (this._options.characterColor = [t, r, i, s]);
1927
+ { method: "characterColor", providedValues: { r: a, g: n, b: h, a: c } }
1928
+ ))
1929
+ return;
1930
+ this._options.characterColor = [a, n, h, c];
1959
1931
  }
1960
1932
  /**
1961
1933
  * Sets the character color mode.
@@ -1973,17 +1945,31 @@ class X extends U {
1973
1945
  /**
1974
1946
  * Sets the cell color for all cells affected by the converter.
1975
1947
  * This is only used when `cellColorMode` is set to `'fixed'`.
1976
- * @param r Red component (0-255).
1948
+ * @param r Red component (0-255) or hex string (e.g., '#FF0000', '#F00', 'FF0000', 'F00').
1977
1949
  * @param g Green component (0-255).
1978
1950
  * @param b Blue component (0-255).
1979
1951
  * @param a Alpha component (0-255).
1980
1952
  */
1981
- cellColor(t, r = t, i = t, s = 255) {
1982
- x.validate(
1983
- [t, r, i, s].every((a) => a >= 0 && a <= 255),
1953
+ cellColor(t, r, i, s = 255) {
1954
+ let a, n, h, c;
1955
+ if (typeof t == "string") {
1956
+ const u = this.parseHexColor(t);
1957
+ if (!u) {
1958
+ x.validate(
1959
+ !1,
1960
+ "Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
1961
+ { method: "cellColor", providedValue: t }
1962
+ );
1963
+ return;
1964
+ }
1965
+ [a, n, h, c] = u;
1966
+ } else if (a = t, n = r !== void 0 ? r : t, h = i !== void 0 ? i : t, c = s, !x.validate(
1967
+ [a, n, h, c].every((u) => u >= 0 && u <= 255),
1984
1968
  "Cell color values must be between 0 and 255",
1985
- { method: "cellColor", providedValues: { r: t, g: r, b: i, a: s } }
1986
- ) && (this._options.cellColor = [t, r, i, s]);
1969
+ { method: "cellColor", providedValues: { r: a, g: n, b: h, a: c } }
1970
+ ))
1971
+ return;
1972
+ this._options.cellColor = [a, n, h, c];
1987
1973
  }
1988
1974
  /**
1989
1975
  * Sets the cell color mode.
@@ -2046,6 +2032,18 @@ class X extends U {
2046
2032
  { method: "flipVertically", providedValue: t }
2047
2033
  ) && (this._options.flipVertically = !!t);
2048
2034
  }
2035
+ /**
2036
+ * Parses a hex color string and returns RGBA values.
2037
+ * @param hex Hex color string (e.g., '#FF0000', '#F00', 'FF0000', 'F00').
2038
+ * @returns RGBA array [r, g, b, a] or null if invalid.
2039
+ */
2040
+ parseHexColor(t) {
2041
+ if (t = t.replace(/^#/, ""), !/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(t))
2042
+ return null;
2043
+ t.length === 3 && (t = t.split("").map((a) => a + a).join(""));
2044
+ const r = parseInt(t.slice(0, 2), 16), i = parseInt(t.slice(2, 4), 16), s = parseInt(t.slice(4, 6), 16);
2045
+ return [r, i, s, 255];
2046
+ }
2049
2047
  }
2050
2048
  var Fe = "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);}}", we = "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);}}", ye = "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);}}", Te = "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);}}", Se = "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);}";
2051
2049
  const Re = {
@@ -2072,7 +2070,7 @@ const Re = {
2072
2070
  /** Range of brightness values to map to ASCII characters */
2073
2071
  brightnessRange: [0, 255]
2074
2072
  };
2075
- class L extends X {
2073
+ class L extends H {
2076
2074
  /**
2077
2075
  * Creates a new TextmodeBrightnessConverter instance.
2078
2076
  * @param renderer Renderer instance for texture creation
@@ -2111,11 +2109,11 @@ class L extends X {
2111
2109
  ) && (this._options.brightnessRange = t);
2112
2110
  }
2113
2111
  }
2114
- const Xe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2112
+ const He = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
2115
2113
  __proto__: null,
2116
2114
  TextmodeBrightnessConverter: L,
2117
2115
  TextmodeConverter: U,
2118
- TextmodeFeatureConverter: X
2116
+ TextmodeFeatureConverter: H
2119
2117
  }, Symbol.toStringTag, { value: "Module" }));
2120
2118
  var Ee = "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);vec2 charCoord=vec2(charCol,charRow)/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);}";
2121
2119
  class Ue {
@@ -2151,7 +2149,7 @@ class Ue {
2151
2149
  render(e) {
2152
2150
  for (const r of this.converters) {
2153
2151
  const i = r.converter;
2154
- i.options.enabled && i instanceof X && i.convert(e);
2152
+ i.options.enabled && i instanceof H && i.convert(e);
2155
2153
  }
2156
2154
  const t = (r, i) => {
2157
2155
  r.begin(), this.renderer.clear();
@@ -2273,14 +2271,8 @@ class Ue {
2273
2271
  */
2274
2272
  dispose() {
2275
2273
  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;
2274
+ e.converter.dispose();
2275
+ this._characterFramebuffer.dispose(), this._primaryColorFramebuffer.dispose(), this._secondaryColorFramebuffer.dispose(), this._rotationFramebuffer.dispose(), this._transformFramebuffer.dispose(), this._resultFramebuffer.dispose(), 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;
2284
2276
  }
2285
2277
  /** Returns the character framebuffer containing the combined result of all converters. */
2286
2278
  get characterFramebuffer() {
@@ -2303,7 +2295,7 @@ class Ue {
2303
2295
  return this._transformFramebuffer;
2304
2296
  }
2305
2297
  }
2306
- class H {
2298
+ class X {
2307
2299
  /**
2308
2300
  * Extracts pixel data from all framebuffers needed for export
2309
2301
  * @param pipeline The conversion pipeline containing framebuffers
@@ -2402,7 +2394,7 @@ class N {
2402
2394
  return `'textmode-export'-${this.generateTimestamp()}`;
2403
2395
  }
2404
2396
  }
2405
- class De extends H {
2397
+ class Ae extends X {
2406
2398
  /**
2407
2399
  * Extracts transform data from transform pixels
2408
2400
  * @param transformPixels Transform framebuffer pixels
@@ -2411,10 +2403,10 @@ class De extends H {
2411
2403
  * @returns Transform data object
2412
2404
  */
2413
2405
  extractTransformData(e, t, r) {
2414
- const i = e[r], s = e[r + 1], a = e[r + 2], n = i === 255, l = s === 255, c = a === 255, u = t[r], d = t[r + 1], f = u + d / 255, g = Math.round(f * 360 / 255 * 100) / 100;
2406
+ const i = e[r], s = e[r + 1], a = e[r + 2], n = i === 255, h = s === 255, c = a === 255, u = t[r], d = t[r + 1], f = u + d / 255, g = Math.round(f * 360 / 255 * 100) / 100;
2415
2407
  return {
2416
2408
  isInverted: n,
2417
- flipHorizontal: l,
2409
+ flipHorizontal: h,
2418
2410
  flipVertical: c,
2419
2411
  rotation: g
2420
2412
  };
@@ -2446,7 +2438,7 @@ class De extends H {
2446
2438
  let i = 0;
2447
2439
  for (let s = 0; s < t.rows; s++)
2448
2440
  for (let a = 0; a < t.cols; a++) {
2449
- const n = i * 4, l = this.getCharacterIndex(
2441
+ const n = i * 4, h = this.getCharacterIndex(
2450
2442
  e.characterPixels,
2451
2443
  n
2452
2444
  );
@@ -2462,7 +2454,7 @@ class De extends H {
2462
2454
  }
2463
2455
  const f = this.calculateCellPosition(a, s, t);
2464
2456
  r.push({
2465
- charIndex: l,
2457
+ charIndex: h,
2466
2458
  primaryColor: c,
2467
2459
  secondaryColor: u,
2468
2460
  transform: d,
@@ -2472,7 +2464,7 @@ class De extends H {
2472
2464
  return r;
2473
2465
  }
2474
2466
  }
2475
- class Ae {
2467
+ class Me {
2476
2468
  /**
2477
2469
  * Gets the glyph index for a given Unicode code point in a Typr.js font
2478
2470
  * @param fontData The Typr.js font data
@@ -2543,29 +2535,29 @@ class Ae {
2543
2535
  */
2544
2536
  glyphToSVGPath(e, t, r, i) {
2545
2537
  if (!e || !e.xs) return "";
2546
- const { xs: s, ys: a, endPts: n, flags: l } = e;
2547
- if (!s || !a || !n || !l) return "";
2538
+ const { xs: s, ys: a, endPts: n, flags: h } = e;
2539
+ if (!s || !a || !n || !h) return "";
2548
2540
  let c = "", u = 0;
2549
2541
  for (let d = 0; d < n.length; d++) {
2550
2542
  const f = n[d];
2551
2543
  if (!(f < u)) {
2552
2544
  if (f >= u) {
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)}`, _++;
2545
+ const g = t + s[u] * i, _ = r - a[u] * i;
2546
+ c += `M${g.toFixed(2)},${_.toFixed(2)}`;
2547
+ let p = u + 1;
2548
+ for (; p <= f; )
2549
+ if ((h[p] & 1) !== 0) {
2550
+ const C = t + s[p] * i, v = r - a[p] * i;
2551
+ c += `L${C.toFixed(2)},${v.toFixed(2)}`, p++;
2560
2552
  } else {
2561
- const C = t + s[_] * i, v = r - a[_] * i;
2562
- let w = _ + 1 > f ? u : _ + 1;
2563
- if ((l[w] & 1) !== 0) {
2553
+ const C = t + s[p] * i, v = r - a[p] * i;
2554
+ let w = p + 1 > f ? u : p + 1;
2555
+ if ((h[w] & 1) !== 0) {
2564
2556
  const R = t + s[w] * i, y = r - a[w] * i;
2565
- c += `Q${C.toFixed(2)},${v.toFixed(2)} ${R.toFixed(2)},${y.toFixed(2)}`, _ = w + 1;
2557
+ c += `Q${C.toFixed(2)},${v.toFixed(2)} ${R.toFixed(2)},${y.toFixed(2)}`, p = w + 1;
2566
2558
  } else {
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;
2559
+ const R = t + s[w] * i, y = r - a[w] * i, P = (C + R) / 2, D = (v + y) / 2;
2560
+ c += `Q${C.toFixed(2)},${v.toFixed(2)} ${P.toFixed(2)},${D.toFixed(2)}`, p = w;
2569
2561
  }
2570
2562
  }
2571
2563
  c += "Z";
@@ -2589,13 +2581,13 @@ class Ae {
2589
2581
  const a = e.codePointAt(0) || 0, n = this.getGlyphIndex(t, a);
2590
2582
  if (n === 0)
2591
2583
  return this.createEmptyPath();
2592
- let l = null;
2584
+ let h = null;
2593
2585
  try {
2594
- t.glyf && t.glyf[n] !== null ? l = t.glyf[n] : m && m.T && m.T.glyf && m.T.glyf._parseGlyf && (l = m.T.glyf._parseGlyf(t, n), t.glyf && l && (t.glyf[n] = l));
2586
+ t.glyf && t.glyf[n] !== null ? h = t.glyf[n] : m && m.T && m.T.glyf && m.T.glyf._parseGlyf && (h = m.T.glyf._parseGlyf(t, n), t.glyf && h && (t.glyf[n] = h));
2595
2587
  } catch (c) {
2596
2588
  console.warn(`Failed to parse glyph ${n}:`, c);
2597
2589
  }
2598
- return l ? this.createGlyphPath(t, l, r, i, s) : this.createEmptyPath();
2590
+ return h ? this.createGlyphPath(t, h, r, i, s) : this.createEmptyPath();
2599
2591
  } catch (a) {
2600
2592
  return console.warn(`Failed to generate path for character "${e}":`, a), this.createEmptyPath();
2601
2593
  }
@@ -2612,19 +2604,19 @@ class Ae {
2612
2604
  * @param advanceWidth Character advance width
2613
2605
  * @returns SVG path data string or null if generation fails
2614
2606
  */
2615
- generatePositionedCharacterPath(e, t, r, i, s, a, n, l) {
2607
+ generatePositionedCharacterPath(e, t, r, i, s, a, n, h) {
2616
2608
  try {
2617
- const c = n / t.head.unitsPerEm, u = l * c, d = r + (s - u) / 2, f = i + (a + n * 0.7) / 2;
2609
+ const c = n / t.head.unitsPerEm, u = h * c, d = r + (s - u) / 2, f = i + (a + n * 0.7) / 2;
2618
2610
  return this.generateCharacterPath(e, t, d, f, n).toSVG() || null;
2619
2611
  } catch (c) {
2620
2612
  return console.warn(`Failed to generate positioned character path for "${e}":`, c), null;
2621
2613
  }
2622
2614
  }
2623
2615
  }
2624
- class Me {
2616
+ class De {
2625
2617
  constructor() {
2626
2618
  o(this, "pathGenerator");
2627
- this.pathGenerator = new Ae();
2619
+ this.pathGenerator = new Me();
2628
2620
  }
2629
2621
  /**
2630
2622
  * Generates the SVG header with metadata
@@ -2678,8 +2670,8 @@ class Me {
2678
2670
  generateTransformAttribute(e, t) {
2679
2671
  const { transform: r, position: i } = e, s = i.cellX + t.cellWidth / 2, a = i.cellY + t.cellHeight / 2, n = [];
2680
2672
  if (r.flipHorizontal || r.flipVertical) {
2681
- const l = r.flipHorizontal ? -1 : 1, c = r.flipVertical ? -1 : 1;
2682
- n.push(`translate(${s} ${a})`), n.push(`scale(${l} ${c})`), n.push(`translate(${-s} ${-a})`);
2673
+ const h = r.flipHorizontal ? -1 : 1, c = r.flipVertical ? -1 : 1;
2674
+ n.push(`translate(${s} ${a})`), n.push(`scale(${h} ${c})`), n.push(`translate(${-s} ${-a})`);
2683
2675
  }
2684
2676
  return r.rotation && n.push(`rotate(${r.rotation} ${s} ${a})`), n.length ? ` transform="${n.join(" ")}"` : "";
2685
2677
  }
@@ -2804,7 +2796,7 @@ class Y {
2804
2796
  o(this, "dataExtractor");
2805
2797
  o(this, "contentGenerator");
2806
2798
  o(this, "fileHandler");
2807
- this.dataExtractor = new De(), this.contentGenerator = new Me(), this.fileHandler = new Ie();
2799
+ this.dataExtractor = new Ae(), this.contentGenerator = new De(), this.fileHandler = new Ie();
2808
2800
  }
2809
2801
  /**
2810
2802
  * Applies default values to SVG export options
@@ -2851,7 +2843,7 @@ class Y {
2851
2843
  }
2852
2844
  }
2853
2845
  }
2854
- class Pe extends H {
2846
+ class Pe extends X {
2855
2847
  /**
2856
2848
  * Extracts character data for TXT generation
2857
2849
  * @param framebufferData Framebuffer pixel data
@@ -2864,7 +2856,7 @@ class Pe extends H {
2864
2856
  var n;
2865
2857
  const s = [];
2866
2858
  let a = 0;
2867
- for (let l = 0; l < t.rows; l++) {
2859
+ for (let h = 0; h < t.rows; h++) {
2868
2860
  const c = [];
2869
2861
  for (let u = 0; u < t.cols; u++) {
2870
2862
  const d = a * 4, f = this.getCharacterIndex(
@@ -2972,7 +2964,7 @@ class j {
2972
2964
  }
2973
2965
  }
2974
2966
  }
2975
- class Ve extends H {
2967
+ class Ve extends X {
2976
2968
  /**
2977
2969
  * Captures the current state of the textmode canvas as image data
2978
2970
  * @param canvas The canvas data containing the rendered textmode graphics
@@ -2984,8 +2976,8 @@ class Ve extends H {
2984
2976
  const i = e.canvas;
2985
2977
  if (t === 1 && r === "transparent")
2986
2978
  return i;
2987
- const s = document.createElement("canvas"), a = s.getContext("2d"), n = Math.round(i.width * t), l = Math.round(i.height * t);
2988
- return s.width = n, s.height = l, r !== "transparent" && (a.fillStyle = r, a.fillRect(0, 0, n, l)), a.imageSmoothingEnabled = !1, a.drawImage(
2979
+ const s = document.createElement("canvas"), a = s.getContext("2d"), n = Math.round(i.width * t), h = Math.round(i.height * t);
2980
+ return s.width = n, s.height = h, r !== "transparent" && (a.fillStyle = r, a.fillRect(0, 0, n, h)), a.imageSmoothingEnabled = !1, a.drawImage(
2989
2981
  i,
2990
2982
  0,
2991
2983
  0,
@@ -2994,7 +2986,7 @@ class Ve extends H {
2994
2986
  0,
2995
2987
  0,
2996
2988
  n,
2997
- l
2989
+ h
2998
2990
  ), s;
2999
2991
  }
3000
2992
  }
@@ -3219,6 +3211,7 @@ class I {
3219
3211
  o(this, "animationFrameId", null);
3220
3212
  o(this, "lastFrameTime", 0);
3221
3213
  o(this, "frameInterval");
3214
+ o(this, "_isLooping", !0);
3222
3215
  o(this, "_frameRate", 0);
3223
3216
  o(this, "lastRenderTime", 0);
3224
3217
  o(this, "_frameCount", 0);
@@ -3226,14 +3219,13 @@ class I {
3226
3219
  o(this, "frameTimeHistory", []);
3227
3220
  o(this, "frameTimeHistorySize", 10);
3228
3221
  o(this, "_pipeline");
3222
+ o(this, "_isDisposed", !1);
3229
3223
  // Standalone canvas properties
3230
3224
  o(this, "_standalone", !1);
3231
3225
  o(this, "_drawCallback", () => {
3232
3226
  });
3233
3227
  o(this, "_resizedCallback", () => {
3234
3228
  });
3235
- // Destroy state
3236
- o(this, "_isDestroyed", !1);
3237
3229
  o(this, "_windowResizeListener", null);
3238
3230
  this.captureSource = e, this._standalone = e === null, this._mode = t.renderMode ?? "auto", this._frameRateLimit = t.frameRate ?? 60, this.frameInterval = 1e3 / this._frameRateLimit;
3239
3231
  }
@@ -3476,11 +3468,7 @@ class I {
3476
3468
  * ```
3477
3469
  */
3478
3470
  render() {
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) {
3471
+ if (this.measureFrameRate(), this._frameCount++, this._isDisposed) {
3484
3472
  console.warn("Cannot render: Required resources have been disposed");
3485
3473
  return;
3486
3474
  }
@@ -3497,13 +3485,15 @@ class I {
3497
3485
  * Start automatic rendering
3498
3486
  */
3499
3487
  startAutoRendering() {
3500
- if (this._mode !== "auto" || this._isDestroyed) return;
3488
+ if (this._mode !== "auto" || !this._isLooping) return;
3501
3489
  this.lastFrameTime = performance.now();
3502
3490
  const e = (t) => {
3503
- if (this._isDestroyed)
3491
+ if (!this._isLooping) {
3492
+ this.animationFrameId = null;
3504
3493
  return;
3494
+ }
3505
3495
  const r = t - this.lastFrameTime;
3506
- r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), this._isDestroyed || (this.animationFrameId = requestAnimationFrame(e));
3496
+ r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), this._isLooping && (this.animationFrameId = requestAnimationFrame(e));
3507
3497
  };
3508
3498
  this.animationFrameId = requestAnimationFrame(e);
3509
3499
  }
@@ -3512,7 +3502,6 @@ class I {
3512
3502
  * Uses a rolling average for smoother frame rate reporting
3513
3503
  */
3514
3504
  measureFrameRate() {
3515
- if (this._isDestroyed) return;
3516
3505
  const e = performance.now();
3517
3506
  if (this.lastRenderTime > 0) {
3518
3507
  const t = e - this.lastRenderTime;
@@ -3553,11 +3542,7 @@ class I {
3553
3542
  * ```
3554
3543
  */
3555
3544
  renderMode(e) {
3556
- if (this._isDestroyed) {
3557
- console.warn("Cannot change render mode: Textmodifier instance has been destroyed");
3558
- return;
3559
- }
3560
- this._mode !== e && (this.stopAutoRendering(), this._mode = e, e === "auto" && this.startAutoRendering());
3545
+ this._mode !== e && (this.stopAutoRendering(), this._mode = e, e === "auto" && this._isLooping && this.startAutoRendering());
3561
3546
  }
3562
3547
  /**
3563
3548
  * Set the maximum frame rate for auto rendering. If called without arguments, returns the current measured frame rate.
@@ -3578,7 +3563,97 @@ class I {
3578
3563
  frameRate(e) {
3579
3564
  if (e === void 0)
3580
3565
  return this._frameRate;
3581
- this._frameRateLimit = e, this.frameInterval = 1e3 / e, this._mode === "auto" && (this.stopAutoRendering(), this.startAutoRendering());
3566
+ this._frameRateLimit = e, this.frameInterval = 1e3 / e, this._mode === "auto" && this._isLooping && (this.stopAutoRendering(), this.startAutoRendering());
3567
+ }
3568
+ /**
3569
+ * Stop the automatic rendering loop while keeping the render mode as 'auto'.
3570
+ *
3571
+ * This method pauses the render loop without changing the render mode, allowing
3572
+ * it to be resumed later with {@link loop}. This is useful for temporarily pausing
3573
+ * animation while maintaining the ability to restart it.
3574
+ *
3575
+ * **Note:** This only affects rendering when in `'auto'` mode. In `'manual'` mode,
3576
+ * this method has no effect since rendering is already controlled manually.
3577
+ *
3578
+ * @example
3579
+ * ```javascript
3580
+ * // Create a textmodifier instance in auto mode
3581
+ * const textmodifier = await textmode.create(canvas);
3582
+ *
3583
+ * // The render loop is running automatically
3584
+ * console.log(textmodifier.isLooping()); // true
3585
+ *
3586
+ * // Stop the automatic rendering loop
3587
+ * textmodifier.noLoop();
3588
+ * console.log(textmodifier.isLooping()); // false
3589
+ *
3590
+ * // Resume the automatic rendering loop
3591
+ * textmodifier.loop();
3592
+ * console.log(textmodifier.isLooping()); // true
3593
+ * ```
3594
+ */
3595
+ noLoop() {
3596
+ this._isLooping && (this._isLooping = !1, this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null));
3597
+ }
3598
+ /**
3599
+ * Resume the automatic rendering loop if it was stopped by {@link noLoop}.
3600
+ *
3601
+ * This method restarts the render loop when in `'auto'` mode. If the render mode
3602
+ * is `'manual'`, the loop state will be set but automatic rendering will not start
3603
+ * until the mode is changed back to `'auto'`.
3604
+ *
3605
+ * @example
3606
+ * ```javascript
3607
+ * // Create a textmodifier instance
3608
+ * const textmodifier = await textmode.create(canvas);
3609
+ *
3610
+ * // Stop the loop
3611
+ * textmodifier.noLoop();
3612
+ *
3613
+ * // Resume the loop
3614
+ * textmodifier.loop();
3615
+ *
3616
+ * // You can also use this pattern for conditional animation
3617
+ * if (someCondition) {
3618
+ * textmodifier.loop();
3619
+ * } else {
3620
+ * textmodifier.noLoop();
3621
+ * }
3622
+ * ```
3623
+ */
3624
+ loop() {
3625
+ this._isLooping || (this._isLooping = !0, this._mode === "auto" && this.startAutoRendering());
3626
+ }
3627
+ /**
3628
+ * Check whether the textmodifier is currently running the automatic render loop.
3629
+ *
3630
+ * Returns `true` when both the render mode is `'auto'` AND the loop is active.
3631
+ * Returns `false` when in `'manual'` mode or when {@link noLoop} has been called.
3632
+ *
3633
+ * @returns True if the automatic render loop is currently active, false otherwise.
3634
+ *
3635
+ * @example
3636
+ * ```javascript
3637
+ * const textmodifier = await textmode.create(canvas);
3638
+ *
3639
+ * // Check loop status in different states
3640
+ * console.log(textmodifier.isLooping()); // true (auto mode, looping)
3641
+ *
3642
+ * textmodifier.noLoop();
3643
+ * console.log(textmodifier.isLooping()); // false (auto mode, not looping)
3644
+ *
3645
+ * textmodifier.renderMode('manual');
3646
+ * console.log(textmodifier.isLooping()); // false (manual mode)
3647
+ *
3648
+ * textmodifier.renderMode('auto');
3649
+ * console.log(textmodifier.isLooping()); // false (auto mode, but loop was stopped)
3650
+ *
3651
+ * textmodifier.loop();
3652
+ * console.log(textmodifier.isLooping()); // true (auto mode, looping)
3653
+ * ```
3654
+ */
3655
+ isLooping() {
3656
+ return this._mode === "auto" && this._isLooping;
3582
3657
  }
3583
3658
  /**
3584
3659
  * Set the font size used for rendering.
@@ -4138,49 +4213,44 @@ class I {
4138
4213
  * ```
4139
4214
  */
4140
4215
  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 = () => {
4216
+ this._isDisposed = !0, this.stopAutoRendering(), this._windowResizeListener && (window.removeEventListener("resize", this._windowResizeListener), this._windowResizeListener = null), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = null), this._pipeline.dispose(), this._font.dispose(), this._grid.dispose(), this._canvasFramebuffer.dispose(), this._renderer.dispose(), 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
4217
  }, this._resizedCallback = () => {
4143
- }, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = []);
4218
+ }, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = [], this._isLooping = !1;
4144
4219
  }
4145
4220
  /** Get the current grid object used for rendering. */
4146
4221
  get grid() {
4147
- if (this._isDestroyed)
4148
- throw new Error("Cannot access grid: Textmodifier instance has been destroyed");
4149
4222
  return this._grid;
4150
4223
  }
4151
4224
  /** Get the current font object used for rendering. */
4152
4225
  get font() {
4153
- if (this._isDestroyed)
4154
- throw new Error("Cannot access font: Textmodifier instance has been destroyed");
4155
4226
  return this._font;
4156
4227
  }
4157
4228
  /** Get the current rendering mode.*/
4158
4229
  get mode() {
4159
- if (this._isDestroyed)
4160
- throw new Error("Cannot access mode: Textmodifier instance has been destroyed");
4161
4230
  return this._mode;
4162
4231
  }
4163
4232
  /** Get the current textmode conversion pipeline. */
4164
4233
  get pipeline() {
4165
- if (this._isDestroyed)
4166
- throw new Error("Cannot access pipeline: Textmodifier instance has been destroyed");
4167
4234
  return this._pipeline;
4168
4235
  }
4169
4236
  /** Get the current frame count. */
4170
4237
  get frameCount() {
4171
- return this._isDestroyed ? 0 : this._frameCount;
4238
+ return this._frameCount;
4239
+ }
4240
+ set frameCount(e) {
4241
+ this._frameCount = e;
4172
4242
  }
4173
4243
  /** Get the width of the canvas. */
4174
4244
  get width() {
4175
- return this._isDestroyed ? 0 : this.textmodeCanvas.width;
4245
+ return this.textmodeCanvas.width;
4176
4246
  }
4177
4247
  /** Get the height of the canvas. */
4178
4248
  get height() {
4179
- return this._isDestroyed ? 0 : this.textmodeCanvas.height;
4249
+ return this.textmodeCanvas.height;
4180
4250
  }
4181
- /** Check if this Textmodifier instance has been destroyed. */
4182
- get isDestroyed() {
4183
- return this._isDestroyed;
4251
+ /** Check if the instance has been disposed/destroyed. */
4252
+ get isDisposed() {
4253
+ return this._isDisposed;
4184
4254
  }
4185
4255
  }
4186
4256
  class O {
@@ -4273,13 +4343,13 @@ class O {
4273
4343
  * ```
4274
4344
  */
4275
4345
  static get version() {
4276
- return "0.1.4-beta.1";
4346
+ return "0.1.4-beta.3";
4277
4347
  }
4278
4348
  constructor() {
4279
4349
  throw new Error("Textmode is a static class and cannot be instantiated.");
4280
4350
  }
4281
4351
  }
4282
- const He = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4352
+ const Xe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4283
4353
  __proto__: null
4284
4354
  }, Symbol.toStringTag, { value: "Module" })), Ne = O.create, Oe = O.setErrorLevel, We = O.version;
4285
4355
  export {
@@ -4289,10 +4359,10 @@ export {
4289
4359
  xe as TextmodeFont,
4290
4360
  ve as TextmodeGrid,
4291
4361
  I as Textmodifier,
4292
- Xe as converters,
4362
+ He as converters,
4293
4363
  Ne as create,
4294
4364
  O as default,
4295
- He as export,
4365
+ Xe as export,
4296
4366
  Oe as setErrorLevel,
4297
4367
  O as textmode,
4298
4368
  We as version