textmode.js 0.1.4-beta.3 → 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.
- package/dist/textmode.esm.js +372 -405
- package/dist/textmode.esm.min.js +492 -525
- package/dist/textmode.umd.js +5 -5
- package/dist/textmode.umd.min.js +6 -6
- package/dist/types/rendering/webgl/Framebuffer.d.ts +0 -4
- package/dist/types/rendering/webgl/Renderer.d.ts +0 -4
- package/dist/types/rendering/webgl/Shader.d.ts +0 -4
- package/dist/types/textmode/Canvas.d.ts +0 -4
- package/dist/types/textmode/ConversionPipeline.d.ts +0 -4
- package/dist/types/textmode/Grid.d.ts +0 -4
- package/dist/types/textmode/Textmodifier.d.ts +4 -3
- package/dist/types/textmode/converters/Converter.d.ts +0 -4
- package/dist/types/textmode/converters/FeatureConverter.d.ts +10 -4
- package/dist/types/textmode/font/TextmodeFont.d.ts +0 -4
- package/package.json +1 -1
package/dist/textmode.esm.min.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
var se = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var
|
|
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);
|
|
7
7
|
super(s);
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
o(this, "originalError");
|
|
9
|
+
o(this, "context");
|
|
10
10
|
this.name = "TextmodeError", this.originalError = r, this.context = i;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
@@ -18,8 +18,8 @@ class F extends Error {
|
|
|
18
18
|
i += `
|
|
19
19
|
|
|
20
20
|
📋 Context:`;
|
|
21
|
-
for (const [s,
|
|
22
|
-
const n = F.formatValue(
|
|
21
|
+
for (const [s, a] of Object.entries(r)) {
|
|
22
|
+
const n = F.formatValue(a);
|
|
23
23
|
i += `
|
|
24
24
|
- ${s}: ${n}`;
|
|
25
25
|
}
|
|
@@ -41,15 +41,15 @@ class F extends Error {
|
|
|
41
41
|
return t.length === 0 ? "[]" : t.length <= 5 ? `[${t.map((r) => F.formatValue(r)).join(", ")}]` : `[${t.slice(0, 3).map((r) => F.formatValue(r)).join(", ")}, ... +${t.length - 3} more]`;
|
|
42
42
|
if (typeof t == "object") {
|
|
43
43
|
const r = Object.keys(t);
|
|
44
|
-
return r.length === 0 ? "{}" : r.length <= 3 ? `{ ${r.map((
|
|
44
|
+
return r.length === 0 ? "{}" : r.length <= 3 ? `{ ${r.map((a) => `${a}: ${F.formatValue(t[a])}`).join(", ")} }` : `{ ${r.slice(0, 2).map((s) => `${s}: ${F.formatValue(t[s])}`).join(", ")}, ... +${r.length - 2} more }`;
|
|
45
45
|
}
|
|
46
46
|
return String(t);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
var ne = /* @__PURE__ */ ((
|
|
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", {
|
|
53
53
|
globalLevel: 3
|
|
54
54
|
/* THROW */
|
|
55
55
|
});
|
|
@@ -103,19 +103,19 @@ const E = class E {
|
|
|
103
103
|
this._options.globalLevel = e;
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
|
-
|
|
106
|
+
o(E, "_instance", null);
|
|
107
107
|
let $ = E;
|
|
108
108
|
const x = $.getInstance();
|
|
109
|
-
class
|
|
109
|
+
class oe {
|
|
110
110
|
constructor(e, t, r = t, i = {}) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
o(this, "gl");
|
|
112
|
+
o(this, "_framebuffer");
|
|
113
|
+
o(this, "_texture");
|
|
114
|
+
o(this, "_width");
|
|
115
|
+
o(this, "_height");
|
|
116
|
+
o(this, "options");
|
|
117
|
+
o(this, "previousState", null);
|
|
118
|
+
o(this, "_pixels", null);
|
|
119
119
|
this.gl = e, this._width = t, this._height = r, this.options = {
|
|
120
120
|
filter: "nearest",
|
|
121
121
|
wrap: "clamp",
|
|
@@ -189,16 +189,16 @@ class ae {
|
|
|
189
189
|
get(e, t, r, i) {
|
|
190
190
|
const { gl: s } = this;
|
|
191
191
|
if (e === void 0 && t === void 0) {
|
|
192
|
-
const
|
|
193
|
-
return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(0, 0, this._width, this._height, s.RGBA, s.UNSIGNED_BYTE,
|
|
192
|
+
const a = new Uint8Array(this._width * this._height * 4), n = s.getParameter(s.FRAMEBUFFER_BINDING);
|
|
193
|
+
return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(0, 0, this._width, this._height, s.RGBA, s.UNSIGNED_BYTE, a), s.bindFramebuffer(s.FRAMEBUFFER, n), a;
|
|
194
194
|
} else if (r === void 0 && i === void 0) {
|
|
195
195
|
(e < 0 || t < 0 || e >= this._width || t >= this._height) && (console.warn("The x and y values passed to Framebuffer.get are outside of its range and will be clamped."), e = Math.max(0, Math.min(e, this._width - 1)), t = Math.max(0, Math.min(t, this._height - 1)));
|
|
196
|
-
const
|
|
197
|
-
return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, 1, 1, s.RGBA, s.UNSIGNED_BYTE,
|
|
196
|
+
const a = new Uint8Array(4), n = s.getParameter(s.FRAMEBUFFER_BINDING);
|
|
197
|
+
return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, 1, 1, s.RGBA, s.UNSIGNED_BYTE, a), s.bindFramebuffer(s.FRAMEBUFFER, n), [a[0], a[1], a[2], a[3]];
|
|
198
198
|
} else {
|
|
199
199
|
e = Math.max(0, Math.min(e, this._width - 1)), t = Math.max(0, Math.min(t, this._height - 1)), r = Math.max(1, Math.min(r, this._width - e)), i = Math.max(1, Math.min(i, this._height - t));
|
|
200
|
-
const
|
|
201
|
-
return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, r, i, s.RGBA, s.UNSIGNED_BYTE,
|
|
200
|
+
const a = new Uint8Array(r * i * 4), n = s.getParameter(s.FRAMEBUFFER_BINDING);
|
|
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
204
|
/**
|
|
@@ -209,12 +209,6 @@ class ae {
|
|
|
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
|
}
|
|
@@ -233,29 +227,29 @@ class ae {
|
|
|
233
227
|
}
|
|
234
228
|
class Q {
|
|
235
229
|
constructor(e, t, r) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
230
|
+
o(this, "gl");
|
|
231
|
+
o(this, "x");
|
|
232
|
+
o(this, "y");
|
|
239
233
|
this.gl = e, this.x = t, this.y = r;
|
|
240
234
|
}
|
|
241
235
|
}
|
|
242
|
-
class
|
|
236
|
+
class M {
|
|
243
237
|
constructor(e, t, r, i, s) {
|
|
244
238
|
/** The WebGL rendering context */
|
|
245
|
-
|
|
239
|
+
o(this, "gl");
|
|
246
240
|
/** The vertex buffer containing position and texture coordinates */
|
|
247
|
-
|
|
241
|
+
o(this, "vertexBuffer");
|
|
248
242
|
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
249
|
-
|
|
243
|
+
o(this, "vertexCount", 6);
|
|
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
|
|
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 /
|
|
256
|
-
let
|
|
257
|
-
|
|
258
|
-
const v = this.generateVertices(
|
|
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,18 +300,18 @@ 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
|
|
310
|
-
constructor(t, r, i, s,
|
|
303
|
+
class le extends Q {
|
|
304
|
+
constructor(t, r, i, s, a) {
|
|
311
305
|
super(t, r, i);
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
this.width = s, this.height =
|
|
306
|
+
o(this, "width");
|
|
307
|
+
o(this, "height");
|
|
308
|
+
this.width = s, this.height = a;
|
|
315
309
|
}
|
|
316
310
|
/**
|
|
317
311
|
* Render the filled rectangle using the existing Rectangle geometry.
|
|
318
312
|
*/
|
|
319
313
|
renderFill() {
|
|
320
|
-
new
|
|
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,30 +320,30 @@ class he extends Q {
|
|
|
326
320
|
*/
|
|
327
321
|
renderStroke(t) {
|
|
328
322
|
if (t <= 0) return;
|
|
329
|
-
const r = new
|
|
330
|
-
r.render(), i.render(), s.render(),
|
|
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);
|
|
324
|
+
r.render(), i.render(), s.render(), a.render();
|
|
331
325
|
}
|
|
332
326
|
}
|
|
333
|
-
class
|
|
334
|
-
constructor(e, t, r, i, s,
|
|
327
|
+
class he {
|
|
328
|
+
constructor(e, t, r, i, s, a) {
|
|
335
329
|
/** The WebGL rendering context */
|
|
336
|
-
|
|
330
|
+
o(this, "gl");
|
|
337
331
|
/** The vertex buffer containing position and texture coordinates */
|
|
338
|
-
|
|
332
|
+
o(this, "vertexBuffer");
|
|
339
333
|
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
340
|
-
|
|
334
|
+
o(this, "vertexCount", 6);
|
|
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),
|
|
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
|
|
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 =
|
|
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,
|
|
402
|
+
generateLineVertices(e, t, r, i, s, a, n, h) {
|
|
409
403
|
return new Float32Array([
|
|
410
404
|
e,
|
|
411
405
|
t,
|
|
@@ -418,7 +412,7 @@ class le {
|
|
|
418
412
|
1,
|
|
419
413
|
// corner2 (start - perpendicular)
|
|
420
414
|
s,
|
|
421
|
-
|
|
415
|
+
a,
|
|
422
416
|
1,
|
|
423
417
|
0,
|
|
424
418
|
// corner3 (end + perpendicular)
|
|
@@ -428,12 +422,12 @@ class le {
|
|
|
428
422
|
1,
|
|
429
423
|
// corner2 (start - perpendicular)
|
|
430
424
|
n,
|
|
431
|
-
|
|
425
|
+
h,
|
|
432
426
|
1,
|
|
433
427
|
1,
|
|
434
428
|
// corner4 (end - perpendicular)
|
|
435
429
|
s,
|
|
436
|
-
|
|
430
|
+
a,
|
|
437
431
|
1,
|
|
438
432
|
0
|
|
439
433
|
// corner3 (end + perpendicular)
|
|
@@ -450,11 +444,11 @@ class le {
|
|
|
450
444
|
}
|
|
451
445
|
}
|
|
452
446
|
class ce extends Q {
|
|
453
|
-
constructor(t, r, i, s,
|
|
447
|
+
constructor(t, r, i, s, a) {
|
|
454
448
|
super(t, r, i);
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
this.x2 = s, this.y2 =
|
|
449
|
+
o(this, "x2");
|
|
450
|
+
o(this, "y2");
|
|
451
|
+
this.x2 = s, this.y2 = a;
|
|
458
452
|
}
|
|
459
453
|
/**
|
|
460
454
|
* Lines don't support fill rendering - this method does nothing.
|
|
@@ -468,23 +462,23 @@ class ce extends Q {
|
|
|
468
462
|
*/
|
|
469
463
|
renderStroke(t) {
|
|
470
464
|
if (t <= 0) return;
|
|
471
|
-
new
|
|
465
|
+
new he(this.gl, this.x, this.y, this.x2, this.y2, t).render();
|
|
472
466
|
}
|
|
473
467
|
}
|
|
474
468
|
class T {
|
|
475
469
|
constructor(e, t, r) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
470
|
+
o(this, "gl");
|
|
471
|
+
o(this, "program");
|
|
472
|
+
o(this, "uniformLocations", /* @__PURE__ */ new Map());
|
|
473
|
+
o(this, "attributeLocations", /* @__PURE__ */ new Map());
|
|
474
|
+
o(this, "textureUnitCounter", 0);
|
|
481
475
|
this.gl = e, this.program = this.createProgram(t, r), this.cacheLocations();
|
|
482
476
|
}
|
|
483
477
|
createProgram(e, t) {
|
|
484
478
|
const r = this.createShader(this.gl.VERTEX_SHADER, e), i = this.createShader(this.gl.FRAGMENT_SHADER, t), s = this.gl.createProgram();
|
|
485
479
|
if (this.gl.attachShader(s, r), this.gl.attachShader(s, i), this.gl.linkProgram(s), !this.gl.getProgramParameter(s, this.gl.LINK_STATUS)) {
|
|
486
|
-
const
|
|
487
|
-
throw new Error(`Shader program link error: ${
|
|
480
|
+
const a = this.gl.getProgramInfoLog(s);
|
|
481
|
+
throw new Error(`Shader program link error: ${a}`);
|
|
488
482
|
}
|
|
489
483
|
return this.gl.deleteShader(r), this.gl.deleteShader(i), s;
|
|
490
484
|
}
|
|
@@ -534,7 +528,7 @@ class T {
|
|
|
534
528
|
this.gl.uniform1i(r, t ? 1 : 0);
|
|
535
529
|
else if (Array.isArray(t))
|
|
536
530
|
if (i && (i.type === this.gl.INT_VEC2 || i.type === this.gl.INT_VEC3 || i.type === this.gl.INT_VEC4)) {
|
|
537
|
-
const s = t.map((
|
|
531
|
+
const s = t.map((a) => Math.floor(a));
|
|
538
532
|
switch (s.length) {
|
|
539
533
|
case 2:
|
|
540
534
|
this.gl.uniform2iv(r, s);
|
|
@@ -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
|
*/
|
|
@@ -627,22 +615,22 @@ class T {
|
|
|
627
615
|
var S = "attribute vec2 a_position;attribute vec2 a_texCoord;varying vec2 v_uv;uniform float u_rotation;uniform vec2 u_center;uniform float u_aspectRatio;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){v_uv=a_texCoord;vec2 pos=a_position;pos-=u_center;pos.x*=u_aspectRatio;pos=rotate2D(-u_rotation)*pos;pos.x/=u_aspectRatio;pos+=u_center;gl_Position=vec4(pos,0.0,1.0);}", ue = "precision lowp float;uniform sampler2D u_texture;varying vec2 v_uv;void main(){gl_FragColor=texture2D(u_texture,v_uv);}", de = "precision lowp float;uniform vec4 u_color;void main(){gl_FragColor=u_color;}";
|
|
628
616
|
class fe {
|
|
629
617
|
constructor(e) {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
618
|
+
o(this, "gl");
|
|
619
|
+
o(this, "imageShader");
|
|
620
|
+
o(this, "solidColorShader");
|
|
621
|
+
o(this, "currentShader", null);
|
|
634
622
|
// Fill state management - default: white fill enabled
|
|
635
|
-
|
|
636
|
-
|
|
623
|
+
o(this, "currentFillColor", [1, 1, 1, 1]);
|
|
624
|
+
o(this, "fillMode", !0);
|
|
637
625
|
// Stroke state management - default: black stroke enabled, weight 1
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
626
|
+
o(this, "currentStrokeColor", [0, 0, 0, 1]);
|
|
627
|
+
o(this, "currentStrokeWeight", 1);
|
|
628
|
+
o(this, "strokeMode", !0);
|
|
641
629
|
// Transformation state management
|
|
642
|
-
|
|
630
|
+
o(this, "currentRotation", 0);
|
|
643
631
|
// in degrees
|
|
644
632
|
// State stack for push/pop functionality
|
|
645
|
-
|
|
633
|
+
o(this, "stateStack", []);
|
|
646
634
|
this.gl = e, this.imageShader = new T(this.gl, S, ue), this.solidColorShader = new T(this.gl, S, de), this.gl.enable(this.gl.BLEND), this.gl.blendEquation(this.gl.FUNC_ADD), this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
|
|
647
635
|
}
|
|
648
636
|
/**
|
|
@@ -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
|
|
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:
|
|
763
|
-
this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio",
|
|
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
|
|
770
|
-
this.fillMode && (this.shader(
|
|
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,31 +770,31 @@ 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
|
|
786
|
-
this.setUniform("u_rotation", R), this.setUniform("u_center", [w,
|
|
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
|
|
793
|
-
this.shader(
|
|
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),
|
|
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
|
|
803
|
-
return { centerX: f, centerY: g, radians:
|
|
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
|
|
807
795
|
*/
|
|
808
796
|
createFramebuffer(e, t, r = {}) {
|
|
809
|
-
return new
|
|
797
|
+
return new oe(this.gl, e, t, r);
|
|
810
798
|
}
|
|
811
799
|
/**
|
|
812
800
|
* Fill the current framebuffer with a solid color
|
|
@@ -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
|
|
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:
|
|
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",
|
|
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(
|
|
864
|
-
var e = function(s,
|
|
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,
|
|
@@ -870,119 +852,119 @@ m.parse = function(h) {
|
|
|
870
852
|
hmtx: c.hmtx,
|
|
871
853
|
loca: c.loca,
|
|
872
854
|
glyf: c.glyf
|
|
873
|
-
}, d = { _data: s, _index:
|
|
855
|
+
}, d = { _data: s, _index: a, _offset: n };
|
|
874
856
|
for (var f in u) {
|
|
875
857
|
var g = m.findTable(s, f, n);
|
|
876
858
|
if (g) {
|
|
877
|
-
var
|
|
878
|
-
|
|
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(
|
|
864
|
+
}, t = new Uint8Array(l), r = {}, i = e(t, 0, 0, r);
|
|
883
865
|
return [i];
|
|
884
866
|
};
|
|
885
|
-
m.findTable = function(
|
|
886
|
-
for (var r = m.B, i = r.readUshort(
|
|
887
|
-
var n = r.readASCII(
|
|
888
|
-
r.readUint(
|
|
889
|
-
var
|
|
890
|
-
if (n == e) return [
|
|
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(
|
|
879
|
+
readShort: function(l, e) {
|
|
898
880
|
var t = m.B.t.uint16;
|
|
899
|
-
return t[0] =
|
|
881
|
+
return t[0] = l[e] << 8 | l[e + 1], m.B.t.int16[0];
|
|
900
882
|
},
|
|
901
|
-
readUshort: function(
|
|
902
|
-
return
|
|
883
|
+
readUshort: function(l, e) {
|
|
884
|
+
return l[e] << 8 | l[e + 1];
|
|
903
885
|
},
|
|
904
|
-
readUshorts: function(
|
|
886
|
+
readUshorts: function(l, e, t) {
|
|
905
887
|
for (var r = [], i = 0; i < t; i++)
|
|
906
|
-
r.push(m.B.readUshort(
|
|
888
|
+
r.push(m.B.readUshort(l, e + i * 2));
|
|
907
889
|
return r;
|
|
908
890
|
},
|
|
909
|
-
readUint: function(
|
|
891
|
+
readUint: function(l, e) {
|
|
910
892
|
var t = m.B.t.uint8;
|
|
911
|
-
return t[3] =
|
|
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(
|
|
914
|
-
for (var r = "", i = 0; i < t; i++) r += String.fromCharCode(
|
|
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
|
|
901
|
+
var l = new ArrayBuffer(8);
|
|
920
902
|
return {
|
|
921
|
-
uint8: new Uint8Array(
|
|
922
|
-
int16: new Int16Array(
|
|
923
|
-
uint16: new Uint16Array(
|
|
924
|
-
uint32: new Uint32Array(
|
|
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(
|
|
911
|
+
parseTab: function(l, e, t) {
|
|
930
912
|
var r = { tables: [], ids: {}, off: e };
|
|
931
|
-
|
|
932
|
-
var i = m.B, s = i.readUshort,
|
|
933
|
-
s(
|
|
934
|
-
var n = s(
|
|
913
|
+
l = new Uint8Array(l.buffer, e, t), e = 0;
|
|
914
|
+
var i = m.B, s = i.readUshort, a = m.T.cmap;
|
|
915
|
+
s(l, e), e += 2;
|
|
916
|
+
var n = s(l, e);
|
|
935
917
|
e += 2;
|
|
936
|
-
for (var
|
|
937
|
-
var u = s(
|
|
918
|
+
for (var h = [], c = 0; c < n; c++) {
|
|
919
|
+
var u = s(l, e);
|
|
938
920
|
e += 2;
|
|
939
|
-
var d = s(
|
|
921
|
+
var d = s(l, e);
|
|
940
922
|
e += 2;
|
|
941
|
-
var f = i.readUint(
|
|
923
|
+
var f = i.readUint(l, e);
|
|
942
924
|
e += 4;
|
|
943
|
-
var g = "p" + u + "e" + d,
|
|
944
|
-
if (
|
|
945
|
-
|
|
946
|
-
var
|
|
947
|
-
|
|
948
|
-
var b =
|
|
949
|
-
b == 4 ?
|
|
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] =
|
|
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(
|
|
956
|
-
var r = m.B, i = r.readUshort, s = r.readUshorts,
|
|
937
|
+
parse4: function(l, e, t) {
|
|
938
|
+
var r = m.B, i = r.readUshort, s = r.readUshorts, a = e;
|
|
957
939
|
e += 2;
|
|
958
|
-
var n = i(
|
|
959
|
-
e += 2, i(
|
|
960
|
-
var
|
|
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 =
|
|
963
|
-
t.searchRange = i(
|
|
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(
|
|
966
|
-
return t.idRangeOffset = s(
|
|
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(
|
|
950
|
+
parse12: function(l, e, t) {
|
|
969
951
|
var r = m.B, i = r.readUint;
|
|
970
|
-
e += 4, i(
|
|
971
|
-
var s = i(
|
|
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
|
-
for (var
|
|
974
|
-
|
|
955
|
+
for (var a = t.groups = new Uint32Array(s), n = 0; n < s; n += 3)
|
|
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(
|
|
961
|
+
parseTab: function(l, e, t) {
|
|
980
962
|
var r = m.B, i = {};
|
|
981
|
-
return e += 18, i.unitsPerEm = r.readUshort(
|
|
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(
|
|
967
|
+
parseTab: function(l, e, t) {
|
|
986
968
|
var r = m.B, i = {};
|
|
987
969
|
e += 4;
|
|
988
970
|
for (var s = [
|
|
@@ -1002,79 +984,79 @@ m.T.hhea = {
|
|
|
1002
984
|
"res3",
|
|
1003
985
|
"metricDataFormat",
|
|
1004
986
|
"numberOfHMetrics"
|
|
1005
|
-
],
|
|
1006
|
-
var n = s[
|
|
1007
|
-
i[n] = l
|
|
987
|
+
], a = 0; a < s.length; a++) {
|
|
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(
|
|
1014
|
-
for (var i = m.B, s = [],
|
|
1015
|
-
c = i.readUshort(
|
|
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
|
-
s.push(c),
|
|
1018
|
-
return { aWidth: s, lsBearing:
|
|
999
|
+
s.push(c), a.push(u), d++;
|
|
1000
|
+
return { aWidth: s, lsBearing: a };
|
|
1019
1001
|
}
|
|
1020
1002
|
};
|
|
1021
1003
|
m.T.maxp = {
|
|
1022
|
-
parseTab: function(
|
|
1004
|
+
parseTab: function(l, e, t) {
|
|
1023
1005
|
var r = m.B, i = r.readUshort, s = {};
|
|
1024
|
-
return r.readUint(
|
|
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(
|
|
1029
|
-
var i = m.B, s = [],
|
|
1030
|
-
if (
|
|
1031
|
-
if (
|
|
1010
|
+
parseTab: function(l, e, t, r) {
|
|
1011
|
+
var i = m.B, s = [], a = r.head.indexToLocFormat, n = r.maxp.numGlyphs + 1;
|
|
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(
|
|
1037
|
-
for (var i = [], s = r.maxp.numGlyphs,
|
|
1018
|
+
parseTab: function(l, e, t, r) {
|
|
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(
|
|
1041
|
-
var t = m.B, r =
|
|
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",
|
|
1044
|
-
if (
|
|
1045
|
-
if (
|
|
1046
|
-
|
|
1047
|
-
for (var n = 0; n <
|
|
1048
|
-
|
|
1049
|
-
var
|
|
1050
|
-
if (s += 2, r.length - s <
|
|
1051
|
-
s +=
|
|
1052
|
-
var c =
|
|
1053
|
-
|
|
1025
|
+
var s = m.findTable(r, "glyf", l._offset)[0] + i[e], a = {};
|
|
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;
|
|
1027
|
+
if (a.noc > 0) {
|
|
1028
|
+
a.endPts = [];
|
|
1029
|
+
for (var n = 0; n < a.noc; n++)
|
|
1030
|
+
a.endPts.push(t.readUshort(r, s)), s += 2;
|
|
1031
|
+
var h = t.readUshort(r, s);
|
|
1032
|
+
if (s += 2, r.length - s < h) return null;
|
|
1033
|
+
s += h;
|
|
1034
|
+
var c = a.endPts[a.noc - 1] + 1;
|
|
1035
|
+
a.flags = [];
|
|
1054
1036
|
for (var n = 0; n < c; n++) {
|
|
1055
1037
|
var u = r[s];
|
|
1056
|
-
if (s++,
|
|
1038
|
+
if (s++, a.flags.push(u), u & 8) {
|
|
1057
1039
|
var d = r[s];
|
|
1058
1040
|
s++;
|
|
1059
1041
|
for (var f = 0; f < d; f++)
|
|
1060
|
-
|
|
1042
|
+
a.flags.push(u), n++;
|
|
1061
1043
|
}
|
|
1062
1044
|
}
|
|
1063
|
-
|
|
1045
|
+
a.xs = [];
|
|
1064
1046
|
for (var n = 0; n < c; n++) {
|
|
1065
|
-
var g = (
|
|
1066
|
-
g ? (
|
|
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 = (
|
|
1071
|
-
g ? (
|
|
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
|
|
1074
|
-
|
|
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
|
-
|
|
1077
|
-
return
|
|
1058
|
+
a.parts = [];
|
|
1059
|
+
return a;
|
|
1078
1060
|
}
|
|
1079
1061
|
};
|
|
1080
1062
|
typeof module < "u" && module.exports ? module.exports = m : typeof window < "u" && (window.Typr = m);
|
|
@@ -1109,10 +1091,10 @@ class me {
|
|
|
1109
1091
|
for (let r = 0; r < e.startCount.length; r++) {
|
|
1110
1092
|
const i = e.startCount[r], s = e.endCount[r];
|
|
1111
1093
|
if (!(i === 65535 && s === 65535)) {
|
|
1112
|
-
for (let
|
|
1113
|
-
if (this._calculateGlyphIndexFormat4(e,
|
|
1114
|
-
const
|
|
1115
|
-
t.push(
|
|
1094
|
+
for (let a = i; a <= s; a++)
|
|
1095
|
+
if (this._calculateGlyphIndexFormat4(e, a, r) > 0) {
|
|
1096
|
+
const h = String.fromCodePoint(a);
|
|
1097
|
+
t.push(h);
|
|
1116
1098
|
}
|
|
1117
1099
|
}
|
|
1118
1100
|
}
|
|
@@ -1128,9 +1110,9 @@ class me {
|
|
|
1128
1110
|
if (!e.groups)
|
|
1129
1111
|
return t;
|
|
1130
1112
|
for (let r = 0; r < e.groups.length; r += 3) {
|
|
1131
|
-
const i = e.groups[r], s = e.groups[r + 1],
|
|
1113
|
+
const i = e.groups[r], s = e.groups[r + 1], a = e.groups[r + 2];
|
|
1132
1114
|
for (let n = i; n <= s; n++)
|
|
1133
|
-
if (
|
|
1115
|
+
if (a + (n - i) > 0) {
|
|
1134
1116
|
const c = String.fromCodePoint(n);
|
|
1135
1117
|
t.push(c);
|
|
1136
1118
|
}
|
|
@@ -1181,9 +1163,9 @@ class ge {
|
|
|
1181
1163
|
* @param renderer The WebGL renderer instance
|
|
1182
1164
|
*/
|
|
1183
1165
|
constructor(e) {
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1166
|
+
o(this, "_textureCanvas");
|
|
1167
|
+
o(this, "_textureContext");
|
|
1168
|
+
o(this, "_renderer");
|
|
1187
1169
|
this._renderer = e, this._textureCanvas = document.createElement("canvas"), this._textureContext = this._textureCanvas.getContext("2d", { willReadFrequently: !0, alpha: !1 });
|
|
1188
1170
|
}
|
|
1189
1171
|
/**
|
|
@@ -1195,12 +1177,12 @@ 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,
|
|
1199
|
-
this._setupCanvas(
|
|
1200
|
-
const u = this._renderer.createFramebuffer(
|
|
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
|
-
columns:
|
|
1185
|
+
columns: a,
|
|
1204
1186
|
rows: n
|
|
1205
1187
|
};
|
|
1206
1188
|
}
|
|
@@ -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
|
|
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
|
}
|
|
@@ -1238,19 +1220,19 @@ class ge {
|
|
|
1238
1220
|
_applyBlackWhiteThreshold(e = 128) {
|
|
1239
1221
|
const t = this._textureContext.getImageData(0, 0, this._textureCanvas.width, this._textureCanvas.height), r = t.data;
|
|
1240
1222
|
for (let i = 0; i < r.length; i += 4) {
|
|
1241
|
-
const s = 0.299 * r[i] + 0.587 * r[i + 1] + 0.114 * r[i + 2],
|
|
1223
|
+
const s = 0.299 * r[i] + 0.587 * r[i + 1] + 0.114 * r[i + 2], a = e + 32, n = s > a ? 255 : 0;
|
|
1242
1224
|
r[i] = n, r[i + 1] = n, r[i + 2] = n;
|
|
1243
1225
|
}
|
|
1244
1226
|
this._textureContext.putImageData(t, 0, 0);
|
|
1245
1227
|
}
|
|
1246
1228
|
}
|
|
1247
|
-
class
|
|
1229
|
+
class pe {
|
|
1248
1230
|
/**
|
|
1249
1231
|
* Creates a new MetricsCalculation instance.
|
|
1250
1232
|
*/
|
|
1251
1233
|
constructor() {
|
|
1252
|
-
|
|
1253
|
-
|
|
1234
|
+
o(this, "_tempCanvas");
|
|
1235
|
+
o(this, "_tempContext");
|
|
1254
1236
|
this._tempCanvas = document.createElement("canvas"), this._tempContext = this._tempCanvas.getContext("2d");
|
|
1255
1237
|
}
|
|
1256
1238
|
/**
|
|
@@ -1264,9 +1246,9 @@ class _e {
|
|
|
1264
1246
|
calculateMaxGlyphDimensions(e, t, r) {
|
|
1265
1247
|
this._tempContext.font = `${t}px ${r}`;
|
|
1266
1248
|
let i = 0, s = 0;
|
|
1267
|
-
for (const
|
|
1268
|
-
const n = this._tempContext.measureText(
|
|
1269
|
-
|
|
1249
|
+
for (const a of e) {
|
|
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
|
|
1259
|
+
class _e {
|
|
1278
1260
|
/**
|
|
1279
1261
|
* Creates TextmodeCharacter objects with unique color assignments.
|
|
1280
1262
|
* @param characters Array of character strings
|
|
@@ -1283,16 +1265,16 @@ class pe {
|
|
|
1283
1265
|
*/
|
|
1284
1266
|
createCharacterObjects(e, t) {
|
|
1285
1267
|
return e.map((r, i) => {
|
|
1286
|
-
const s = r.codePointAt(0) || 0,
|
|
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
|
|
1290
|
-
|
|
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,
|
|
1294
1276
|
unicode: s,
|
|
1295
|
-
color:
|
|
1277
|
+
color: a,
|
|
1296
1278
|
advanceWidth: n
|
|
1297
1279
|
};
|
|
1298
1280
|
});
|
|
@@ -1314,9 +1296,9 @@ class pe {
|
|
|
1314
1296
|
if (i.idRangeOffset[s] === 0)
|
|
1315
1297
|
return t + i.idDelta[s] & 65535;
|
|
1316
1298
|
{
|
|
1317
|
-
const
|
|
1318
|
-
if (
|
|
1319
|
-
const n = i.glyphIdArray[
|
|
1299
|
+
const a = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
|
|
1300
|
+
if (a >= 0 && a < i.glyphIdArray.length) {
|
|
1301
|
+
const n = i.glyphIdArray[a];
|
|
1320
1302
|
if (n !== 0)
|
|
1321
1303
|
return n + i.idDelta[s] & 65535;
|
|
1322
1304
|
}
|
|
@@ -1372,21 +1354,21 @@ class xe {
|
|
|
1372
1354
|
* @ignore
|
|
1373
1355
|
*/
|
|
1374
1356
|
constructor(e, t = 16) {
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1357
|
+
o(this, "_font");
|
|
1358
|
+
o(this, "_characters", []);
|
|
1359
|
+
o(this, "_fontFramebuffer");
|
|
1360
|
+
o(this, "_fontSize", 16);
|
|
1361
|
+
o(this, "_textureColumns", 0);
|
|
1362
|
+
o(this, "_textureRows", 0);
|
|
1363
|
+
o(this, "_maxGlyphDimensions", { width: 0, height: 0 });
|
|
1364
|
+
o(this, "_fontFace");
|
|
1365
|
+
o(this, "_fontFamilyName", "UrsaFont");
|
|
1384
1366
|
// Component classes
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new
|
|
1367
|
+
o(this, "_characterExtractor");
|
|
1368
|
+
o(this, "_textureAtlas");
|
|
1369
|
+
o(this, "_metricsCalculator");
|
|
1370
|
+
o(this, "_characterColorMapper");
|
|
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
|
|
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() {
|
|
@@ -1556,25 +1532,25 @@ class ve {
|
|
|
1556
1532
|
*/
|
|
1557
1533
|
constructor(e, t, r) {
|
|
1558
1534
|
/** The number of columns in the grid. */
|
|
1559
|
-
|
|
1535
|
+
o(this, "_cols");
|
|
1560
1536
|
/** The number of rows in the grid. */
|
|
1561
|
-
|
|
1537
|
+
o(this, "_rows");
|
|
1562
1538
|
/** The total width of the grid in pixels. */
|
|
1563
|
-
|
|
1539
|
+
o(this, "_width");
|
|
1564
1540
|
/** The total height of the grid in pixels. */
|
|
1565
|
-
|
|
1541
|
+
o(this, "_height");
|
|
1566
1542
|
/** The offset to the outer canvas on the x-axis when centering the grid. */
|
|
1567
|
-
|
|
1543
|
+
o(this, "_offsetX");
|
|
1568
1544
|
/** The offset to the outer canvas on the y-axis when centering the grid. */
|
|
1569
|
-
|
|
1545
|
+
o(this, "_offsetY");
|
|
1570
1546
|
/** Whether the grid dimensions are fixed, or responsive based on the canvas dimensions. */
|
|
1571
|
-
|
|
1547
|
+
o(this, "_fixedDimensions", !1);
|
|
1572
1548
|
/** The canvas element used to determine the grid dimensions. */
|
|
1573
|
-
|
|
1549
|
+
o(this, "_canvas");
|
|
1574
1550
|
/** The width of each cell in the grid. */
|
|
1575
|
-
|
|
1551
|
+
o(this, "_cellWidth");
|
|
1576
1552
|
/** The height of each cell in the grid. */
|
|
1577
|
-
|
|
1553
|
+
o(this, "_cellHeight");
|
|
1578
1554
|
this._canvas = e, this._cellWidth = t, this._cellHeight = r, this.reset();
|
|
1579
1555
|
}
|
|
1580
1556
|
/**
|
|
@@ -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;
|
|
@@ -1691,9 +1661,9 @@ class ve {
|
|
|
1691
1661
|
}
|
|
1692
1662
|
class be {
|
|
1693
1663
|
constructor(e, t = !1, r = {}) {
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1664
|
+
o(this, "_canvas");
|
|
1665
|
+
o(this, "captureSource");
|
|
1666
|
+
o(this, "_isStandalone");
|
|
1697
1667
|
this.captureSource = e, this._isStandalone = t, this._canvas = this.createCanvas(r.width, r.height);
|
|
1698
1668
|
}
|
|
1699
1669
|
createCanvas(e, t) {
|
|
@@ -1703,14 +1673,14 @@ class be {
|
|
|
1703
1673
|
r.width = e || 800, r.height = t || 600, document.body.appendChild(r);
|
|
1704
1674
|
else {
|
|
1705
1675
|
const s = this.captureSource.getBoundingClientRect();
|
|
1706
|
-
let
|
|
1676
|
+
let a = Math.round(s.width), n = Math.round(s.height);
|
|
1707
1677
|
if (this.captureSource instanceof HTMLVideoElement) {
|
|
1708
1678
|
const u = this.captureSource;
|
|
1709
|
-
(
|
|
1679
|
+
(a === 0 || n === 0) && u.videoWidth > 0 && u.videoHeight > 0 && (a = u.videoWidth, n = u.videoHeight);
|
|
1710
1680
|
}
|
|
1711
|
-
r.width =
|
|
1712
|
-
const
|
|
1713
|
-
let c = parseInt(
|
|
1681
|
+
r.width = a, r.height = n, r.style.position = "absolute", r.style.pointerEvents = "none";
|
|
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;
|
|
@@ -1731,8 +1701,8 @@ class be {
|
|
|
1731
1701
|
const r = this.captureSource.getBoundingClientRect();
|
|
1732
1702
|
let i = Math.round(r.width), s = Math.round(r.height);
|
|
1733
1703
|
if (this.captureSource instanceof HTMLVideoElement) {
|
|
1734
|
-
const
|
|
1735
|
-
(i === 0 || s === 0) &&
|
|
1704
|
+
const a = this.captureSource;
|
|
1705
|
+
(i === 0 || s === 0) && a.videoWidth > 0 && a.videoHeight > 0 && (i = a.videoWidth, s = a.videoHeight);
|
|
1736
1706
|
}
|
|
1737
1707
|
this._canvas.width = i, this._canvas.height = s, this.positionOverlayCanvas(this._canvas);
|
|
1738
1708
|
}
|
|
@@ -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
|
}
|
|
@@ -1795,15 +1759,15 @@ class U {
|
|
|
1795
1759
|
* @ignore
|
|
1796
1760
|
*/
|
|
1797
1761
|
constructor(e, t, r, i = {}) {
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1762
|
+
o(this, "renderer");
|
|
1763
|
+
o(this, "fontManager");
|
|
1764
|
+
o(this, "grid");
|
|
1765
|
+
o(this, "_characterFramebuffer");
|
|
1766
|
+
o(this, "_primaryColorFramebuffer");
|
|
1767
|
+
o(this, "_secondaryColorFramebuffer");
|
|
1768
|
+
o(this, "_rotationFramebuffer");
|
|
1769
|
+
o(this, "_transformFramebuffer");
|
|
1770
|
+
o(this, "_options");
|
|
1807
1771
|
this.renderer = e, this.fontManager = t, this.grid = r, this._options = i, this._characterFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._primaryColorFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._secondaryColorFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._rotationFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows), this._transformFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
|
|
1808
1772
|
}
|
|
1809
1773
|
/**
|
|
@@ -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
|
|
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() {
|
|
@@ -1878,9 +1836,9 @@ class Ce {
|
|
|
1878
1836
|
*/
|
|
1879
1837
|
constructor(e, t) {
|
|
1880
1838
|
/** The framebuffer used to store the color palette. */
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1839
|
+
o(this, "_framebuffer");
|
|
1840
|
+
o(this, "_renderer");
|
|
1841
|
+
o(this, "_colors");
|
|
1884
1842
|
this._renderer = e, this._colors = t;
|
|
1885
1843
|
const r = Math.max(this._colors.length, 1);
|
|
1886
1844
|
this._framebuffer = this._renderer.createFramebuffer(r, 1), this._updateFramebuffer();
|
|
@@ -1894,8 +1852,8 @@ class Ce {
|
|
|
1894
1852
|
this._framebuffer.width !== e && this._framebuffer.resize(e, t);
|
|
1895
1853
|
const r = new Uint8Array(e * t * 4);
|
|
1896
1854
|
for (let i = 0; i < e; i++) {
|
|
1897
|
-
const s = i < this._colors.length ? this._colors[i] : [0, 0, 0],
|
|
1898
|
-
r[
|
|
1855
|
+
const s = i < this._colors.length ? this._colors[i] : [0, 0, 0], a = i * 4;
|
|
1856
|
+
r[a] = s[0], r[a + 1] = s[1], r[a + 2] = s[2], r[a + 3] = 255;
|
|
1899
1857
|
}
|
|
1900
1858
|
this._framebuffer.updatePixels(r, e, t);
|
|
1901
1859
|
}
|
|
@@ -1925,10 +1883,10 @@ class Ce {
|
|
|
1925
1883
|
return this._framebuffer.texture;
|
|
1926
1884
|
}
|
|
1927
1885
|
}
|
|
1928
|
-
class
|
|
1886
|
+
class H extends U {
|
|
1929
1887
|
constructor(t, r, i, s = {}) {
|
|
1930
1888
|
super(t, r, i, s);
|
|
1931
|
-
|
|
1889
|
+
o(this, "palette");
|
|
1932
1890
|
this.palette = new Ce(this.renderer, this.fontManager.getCharacterColors(" .:-=+*%@#"));
|
|
1933
1891
|
}
|
|
1934
1892
|
/**
|
|
@@ -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
|
|
1954
|
-
|
|
1955
|
-
|
|
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:
|
|
1958
|
-
)
|
|
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
|
|
1982
|
-
|
|
1983
|
-
|
|
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:
|
|
1986
|
-
)
|
|
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
|
|
2073
|
+
class L extends H {
|
|
2076
2074
|
/**
|
|
2077
2075
|
* Creates a new TextmodeBrightnessConverter instance.
|
|
2078
2076
|
* @param renderer Renderer instance for texture creation
|
|
@@ -2082,12 +2080,12 @@ class L extends X {
|
|
|
2082
2080
|
*/
|
|
2083
2081
|
constructor(t, r, i) {
|
|
2084
2082
|
super(t, r, i, { ...Re });
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2083
|
+
o(this, "sampleShader");
|
|
2084
|
+
o(this, "colorFillShader");
|
|
2085
|
+
o(this, "charMappingShader");
|
|
2086
|
+
o(this, "transformFillShader");
|
|
2087
|
+
o(this, "rotationFillShader");
|
|
2088
|
+
o(this, "sampleFramebuffer");
|
|
2091
2089
|
this.sampleShader = new T(t.context, S, Fe), this.colorFillShader = new T(t.context, S, we), this.transformFillShader = new T(t.context, S, ye), this.rotationFillShader = new T(t.context, S, Te), this.charMappingShader = new T(t.context, S, Se), this.sampleFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
|
|
2092
2090
|
}
|
|
2093
2091
|
convert(t) {
|
|
@@ -2111,11 +2109,11 @@ class L extends X {
|
|
|
2111
2109
|
) && (this._options.brightnessRange = t);
|
|
2112
2110
|
}
|
|
2113
2111
|
}
|
|
2114
|
-
const
|
|
2112
|
+
const He = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2115
2113
|
__proto__: null,
|
|
2116
2114
|
TextmodeBrightnessConverter: L,
|
|
2117
2115
|
TextmodeConverter: U,
|
|
2118
|
-
TextmodeFeatureConverter:
|
|
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 {
|
|
@@ -2127,17 +2125,17 @@ class Ue {
|
|
|
2127
2125
|
* @ignore
|
|
2128
2126
|
*/
|
|
2129
2127
|
constructor(e, t, r) {
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2128
|
+
o(this, "renderer");
|
|
2129
|
+
o(this, "font");
|
|
2130
|
+
o(this, "grid");
|
|
2131
|
+
o(this, "converters");
|
|
2132
|
+
o(this, "_resultFramebuffer");
|
|
2133
|
+
o(this, "_asciiShader");
|
|
2134
|
+
o(this, "_characterFramebuffer");
|
|
2135
|
+
o(this, "_primaryColorFramebuffer");
|
|
2136
|
+
o(this, "_secondaryColorFramebuffer");
|
|
2137
|
+
o(this, "_rotationFramebuffer");
|
|
2138
|
+
o(this, "_transformFramebuffer");
|
|
2141
2139
|
this.renderer = e, this.font = t, this.grid = r, this._asciiShader = this.renderer.createShader(S, Ee), this.converters = [
|
|
2142
2140
|
{ name: "brightness", converter: new L(e, t, r) },
|
|
2143
2141
|
{ name: "custom", converter: new U(e, t, r) }
|
|
@@ -2151,13 +2149,13 @@ 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
|
|
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();
|
|
2158
2156
|
for (const s of this.converters) {
|
|
2159
|
-
const
|
|
2160
|
-
|
|
2157
|
+
const a = s.converter;
|
|
2158
|
+
a.options.enabled && this.renderer.image(i(a), 0, 0);
|
|
2161
2159
|
}
|
|
2162
2160
|
r.end();
|
|
2163
2161
|
};
|
|
@@ -2273,14 +2271,8 @@ class Ue {
|
|
|
2273
2271
|
*/
|
|
2274
2272
|
dispose() {
|
|
2275
2273
|
for (const e of this.converters)
|
|
2276
|
-
e.converter
|
|
2277
|
-
this._characterFramebuffer
|
|
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,19 +2295,19 @@ class Ue {
|
|
|
2303
2295
|
return this._transformFramebuffer;
|
|
2304
2296
|
}
|
|
2305
2297
|
}
|
|
2306
|
-
class
|
|
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
|
|
2310
2302
|
* @returns Object containing all pixel data arrays
|
|
2311
2303
|
*/
|
|
2312
2304
|
extractFramebufferData(e) {
|
|
2313
|
-
const t = e.get("brightness"), r = t == null ? void 0 : t.characterFramebuffer, i = t == null ? void 0 : t.primaryColorFramebuffer, s = t == null ? void 0 : t.secondaryColorFramebuffer,
|
|
2314
|
-
return r == null || r.loadPixels(), i == null || i.loadPixels(), s == null || s.loadPixels(),
|
|
2305
|
+
const t = e.get("brightness"), r = t == null ? void 0 : t.characterFramebuffer, i = t == null ? void 0 : t.primaryColorFramebuffer, s = t == null ? void 0 : t.secondaryColorFramebuffer, a = t == null ? void 0 : t.transformFramebuffer, n = t == null ? void 0 : t.rotationFramebuffer;
|
|
2306
|
+
return r == null || r.loadPixels(), i == null || i.loadPixels(), s == null || s.loadPixels(), a == null || a.loadPixels(), n == null || n.loadPixels(), {
|
|
2315
2307
|
characterPixels: (r == null ? void 0 : r.pixels) || new Uint8Array(0),
|
|
2316
2308
|
primaryColorPixels: (i == null ? void 0 : i.pixels) || new Uint8Array(0),
|
|
2317
2309
|
secondaryColorPixels: (s == null ? void 0 : s.pixels) || new Uint8Array(0),
|
|
2318
|
-
transformPixels: (
|
|
2310
|
+
transformPixels: (a == null ? void 0 : a.pixels) || new Uint8Array(0),
|
|
2319
2311
|
rotationPixels: (n == null ? void 0 : n.pixels) || new Uint8Array(0)
|
|
2320
2312
|
};
|
|
2321
2313
|
}
|
|
@@ -2363,8 +2355,8 @@ class N {
|
|
|
2363
2355
|
*/
|
|
2364
2356
|
downloadFile(e, t, r) {
|
|
2365
2357
|
try {
|
|
2366
|
-
const i = this.createBlob(e, r), s = URL.createObjectURL(i),
|
|
2367
|
-
|
|
2358
|
+
const i = this.createBlob(e, r), s = URL.createObjectURL(i), a = document.createElement("a");
|
|
2359
|
+
a.href = s, a.download = t, a.style.display = "none", a.rel = "noopener", document.body.appendChild(a), a.click(), document.body.removeChild(a), URL.revokeObjectURL(s);
|
|
2368
2360
|
} catch (i) {
|
|
2369
2361
|
throw console.error("Failed to download file:", i), new Error(`File download failed: ${i instanceof Error ? i.message : "Unknown error"}`);
|
|
2370
2362
|
}
|
|
@@ -2402,7 +2394,7 @@ class N {
|
|
|
2402
2394
|
return `'textmode-export'-${this.generateTimestamp()}`;
|
|
2403
2395
|
}
|
|
2404
2396
|
}
|
|
2405
|
-
class
|
|
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],
|
|
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:
|
|
2409
|
+
flipHorizontal: h,
|
|
2418
2410
|
flipVertical: c,
|
|
2419
2411
|
rotation: g
|
|
2420
2412
|
};
|
|
@@ -2445,8 +2437,8 @@ class De extends H {
|
|
|
2445
2437
|
const r = [];
|
|
2446
2438
|
let i = 0;
|
|
2447
2439
|
for (let s = 0; s < t.rows; s++)
|
|
2448
|
-
for (let
|
|
2449
|
-
const n = i * 4,
|
|
2440
|
+
for (let a = 0; a < t.cols; a++) {
|
|
2441
|
+
const n = i * 4, h = this.getCharacterIndex(
|
|
2450
2442
|
e.characterPixels,
|
|
2451
2443
|
n
|
|
2452
2444
|
);
|
|
@@ -2460,9 +2452,9 @@ class De extends H {
|
|
|
2460
2452
|
const g = c;
|
|
2461
2453
|
c = u, u = g;
|
|
2462
2454
|
}
|
|
2463
|
-
const f = this.calculateCellPosition(
|
|
2455
|
+
const f = this.calculateCellPosition(a, s, t);
|
|
2464
2456
|
r.push({
|
|
2465
|
-
charIndex:
|
|
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
|
|
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
|
|
@@ -2489,9 +2481,9 @@ class Ae {
|
|
|
2489
2481
|
if (i.idRangeOffset[s] === 0)
|
|
2490
2482
|
return t + i.idDelta[s] & 65535;
|
|
2491
2483
|
{
|
|
2492
|
-
const
|
|
2493
|
-
if (
|
|
2494
|
-
const n = i.glyphIdArray[
|
|
2484
|
+
const a = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
|
|
2485
|
+
if (a >= 0 && a < i.glyphIdArray.length) {
|
|
2486
|
+
const n = i.glyphIdArray[a];
|
|
2495
2487
|
if (n !== 0)
|
|
2496
2488
|
return n + i.idDelta[s] & 65535;
|
|
2497
2489
|
}
|
|
@@ -2522,15 +2514,15 @@ class Ae {
|
|
|
2522
2514
|
createGlyphPath(e, t, r, i, s) {
|
|
2523
2515
|
if (!t || !t.xs || t.xs.length === 0)
|
|
2524
2516
|
return this.createEmptyPath();
|
|
2525
|
-
const
|
|
2517
|
+
const a = s / e.head.unitsPerEm;
|
|
2526
2518
|
return {
|
|
2527
2519
|
getBoundingBox: () => ({
|
|
2528
|
-
x1: r + t.xMin *
|
|
2529
|
-
y1: i + -t.yMax *
|
|
2530
|
-
x2: r + t.xMax *
|
|
2531
|
-
y2: i + -t.yMin *
|
|
2520
|
+
x1: r + t.xMin * a,
|
|
2521
|
+
y1: i + -t.yMax * a,
|
|
2522
|
+
x2: r + t.xMax * a,
|
|
2523
|
+
y2: i + -t.yMin * a
|
|
2532
2524
|
}),
|
|
2533
|
-
toSVG: () => this.glyphToSVGPath(t, r, i,
|
|
2525
|
+
toSVG: () => this.glyphToSVGPath(t, r, i, a)
|
|
2534
2526
|
};
|
|
2535
2527
|
}
|
|
2536
2528
|
/**
|
|
@@ -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:
|
|
2547
|
-
if (!s || !
|
|
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,
|
|
2554
|
-
c += `M${g.toFixed(2)},${
|
|
2555
|
-
let
|
|
2556
|
-
for (;
|
|
2557
|
-
if ((
|
|
2558
|
-
const C = t + s[
|
|
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[
|
|
2562
|
-
let w =
|
|
2563
|
-
if ((
|
|
2564
|
-
const R = t + s[w] * i, y = r -
|
|
2565
|
-
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${R.toFixed(2)},${y.toFixed(2)}`,
|
|
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) {
|
|
2556
|
+
const R = t + s[w] * i, y = r - a[w] * i;
|
|
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 -
|
|
2568
|
-
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${P.toFixed(2)},${
|
|
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";
|
|
@@ -2586,18 +2578,18 @@ class Ae {
|
|
|
2586
2578
|
*/
|
|
2587
2579
|
generateCharacterPath(e, t, r, i, s) {
|
|
2588
2580
|
try {
|
|
2589
|
-
const
|
|
2581
|
+
const a = e.codePointAt(0) || 0, n = this.getGlyphIndex(t, a);
|
|
2590
2582
|
if (n === 0)
|
|
2591
2583
|
return this.createEmptyPath();
|
|
2592
|
-
let
|
|
2584
|
+
let h = null;
|
|
2593
2585
|
try {
|
|
2594
|
-
t.glyf && t.glyf[n] !== null ?
|
|
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
|
|
2599
|
-
} catch (
|
|
2600
|
-
return console.warn(`Failed to generate path for character "${e}":`,
|
|
2590
|
+
return h ? this.createGlyphPath(t, h, r, i, s) : this.createEmptyPath();
|
|
2591
|
+
} catch (a) {
|
|
2592
|
+
return console.warn(`Failed to generate path for character "${e}":`, a), this.createEmptyPath();
|
|
2601
2593
|
}
|
|
2602
2594
|
}
|
|
2603
2595
|
/**
|
|
@@ -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,
|
|
2607
|
+
generatePositionedCharacterPath(e, t, r, i, s, a, n, h) {
|
|
2616
2608
|
try {
|
|
2617
|
-
const c = n / t.head.unitsPerEm, u =
|
|
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
|
|
2616
|
+
class De {
|
|
2625
2617
|
constructor() {
|
|
2626
|
-
|
|
2627
|
-
this.pathGenerator = new
|
|
2618
|
+
o(this, "pathGenerator");
|
|
2619
|
+
this.pathGenerator = new Me();
|
|
2628
2620
|
}
|
|
2629
2621
|
/**
|
|
2630
2622
|
* Generates the SVG header with metadata
|
|
@@ -2676,12 +2668,12 @@ class Me {
|
|
|
2676
2668
|
* @returns Transform attribute string or empty string
|
|
2677
2669
|
*/
|
|
2678
2670
|
generateTransformAttribute(e, t) {
|
|
2679
|
-
const { transform: r, position: i } = e, s = i.cellX + t.cellWidth / 2,
|
|
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
|
|
2682
|
-
n.push(`translate(${s} ${
|
|
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
|
-
return r.rotation && n.push(`rotate(${r.rotation} ${s} ${
|
|
2676
|
+
return r.rotation && n.push(`rotate(${r.rotation} ${s} ${a})`), n.length ? ` transform="${n.join(" ")}"` : "";
|
|
2685
2677
|
}
|
|
2686
2678
|
/**
|
|
2687
2679
|
* Generates background rectangle for a cell
|
|
@@ -2710,7 +2702,7 @@ class Me {
|
|
|
2710
2702
|
const s = r.characters[e.charIndex];
|
|
2711
2703
|
if (!s)
|
|
2712
2704
|
return "";
|
|
2713
|
-
const
|
|
2705
|
+
const a = this.pathGenerator.generatePositionedCharacterPath(
|
|
2714
2706
|
s.character,
|
|
2715
2707
|
r.font,
|
|
2716
2708
|
e.position.cellX,
|
|
@@ -2720,12 +2712,12 @@ class Me {
|
|
|
2720
2712
|
r.fontSize,
|
|
2721
2713
|
s.advanceWidth
|
|
2722
2714
|
);
|
|
2723
|
-
if (!
|
|
2715
|
+
if (!a)
|
|
2724
2716
|
return "";
|
|
2725
2717
|
const n = this.rgbaToColorString(e.primaryColor);
|
|
2726
2718
|
return i.drawMode === "stroke" ? `
|
|
2727
|
-
<path id="${`path-${e.charIndex}-${e.position.cellX}-${e.position.cellY}`.replace(/\./g, "-")}" d="${
|
|
2728
|
-
<path d="${
|
|
2719
|
+
<path id="${`path-${e.charIndex}-${e.position.cellX}-${e.position.cellY}`.replace(/\./g, "-")}" d="${a}" stroke="${n}" stroke-width="${i.strokeWidth}" fill="none" />` : `
|
|
2720
|
+
<path d="${a}" fill="${n}" />`;
|
|
2729
2721
|
}
|
|
2730
2722
|
/**
|
|
2731
2723
|
* Generates complete SVG content for a single cell
|
|
@@ -2738,9 +2730,9 @@ class Me {
|
|
|
2738
2730
|
generateCellContent(e, t, r, i) {
|
|
2739
2731
|
let s = "";
|
|
2740
2732
|
s += this.generateCellBackground(e, t, i);
|
|
2741
|
-
const
|
|
2742
|
-
return n && (
|
|
2743
|
-
<g${
|
|
2733
|
+
const a = this.generateTransformAttribute(e, t), n = this.generateCharacterPath(e, t, r, i);
|
|
2734
|
+
return n && (a ? (s += `
|
|
2735
|
+
<g${a}>`, s += n, s += `
|
|
2744
2736
|
</g>`) : s += n), s;
|
|
2745
2737
|
}
|
|
2746
2738
|
/**
|
|
@@ -2755,8 +2747,8 @@ class Me {
|
|
|
2755
2747
|
let s = this.generateSVGHeader(t);
|
|
2756
2748
|
s += this.generateBackground(t, i), s += `
|
|
2757
2749
|
<g id="ascii-cells">`;
|
|
2758
|
-
for (const
|
|
2759
|
-
s += this.generateCellContent(
|
|
2750
|
+
for (const a of e)
|
|
2751
|
+
s += this.generateCellContent(a, t, r, i);
|
|
2760
2752
|
return s += this.generateSVGFooter(), s;
|
|
2761
2753
|
}
|
|
2762
2754
|
/**
|
|
@@ -2801,10 +2793,10 @@ class Ie extends N {
|
|
|
2801
2793
|
}
|
|
2802
2794
|
class Y {
|
|
2803
2795
|
constructor() {
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
this.dataExtractor = new
|
|
2796
|
+
o(this, "dataExtractor");
|
|
2797
|
+
o(this, "contentGenerator");
|
|
2798
|
+
o(this, "fileHandler");
|
|
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
|
|
@@ -2829,13 +2821,13 @@ class Y {
|
|
|
2829
2821
|
const r = this.applyDefaultOptions(t), i = this.dataExtractor.extractFramebufferData(e.pipeline), s = this.dataExtractor.extractSVGCellData(
|
|
2830
2822
|
i,
|
|
2831
2823
|
e.grid
|
|
2832
|
-
),
|
|
2824
|
+
), a = this.contentGenerator.generateSVGContent(
|
|
2833
2825
|
s,
|
|
2834
2826
|
e.grid,
|
|
2835
2827
|
e.font,
|
|
2836
2828
|
r
|
|
2837
2829
|
);
|
|
2838
|
-
return this.contentGenerator.optimizeSVGContent(
|
|
2830
|
+
return this.contentGenerator.optimizeSVGContent(a);
|
|
2839
2831
|
}
|
|
2840
2832
|
/**
|
|
2841
2833
|
* Exports SVG content to a downloadable file
|
|
@@ -2851,7 +2843,7 @@ class Y {
|
|
|
2851
2843
|
}
|
|
2852
2844
|
}
|
|
2853
2845
|
}
|
|
2854
|
-
class Pe extends
|
|
2846
|
+
class Pe extends X {
|
|
2855
2847
|
/**
|
|
2856
2848
|
* Extracts character data for TXT generation
|
|
2857
2849
|
* @param framebufferData Framebuffer pixel data
|
|
@@ -2863,15 +2855,15 @@ class Pe extends H {
|
|
|
2863
2855
|
extractCharacterGrid(e, t, r, i = " ") {
|
|
2864
2856
|
var n;
|
|
2865
2857
|
const s = [];
|
|
2866
|
-
let
|
|
2867
|
-
for (let
|
|
2858
|
+
let a = 0;
|
|
2859
|
+
for (let h = 0; h < t.rows; h++) {
|
|
2868
2860
|
const c = [];
|
|
2869
2861
|
for (let u = 0; u < t.cols; u++) {
|
|
2870
|
-
const d =
|
|
2862
|
+
const d = a * 4, f = this.getCharacterIndex(
|
|
2871
2863
|
e.characterPixels,
|
|
2872
2864
|
d
|
|
2873
2865
|
), g = ((n = r.characters[f]) == null ? void 0 : n.character) || i;
|
|
2874
|
-
c.push(g),
|
|
2866
|
+
c.push(g), a++;
|
|
2875
2867
|
}
|
|
2876
2868
|
s.push(c);
|
|
2877
2869
|
}
|
|
@@ -2888,8 +2880,8 @@ class Be {
|
|
|
2888
2880
|
generateTXTContent(e, t) {
|
|
2889
2881
|
const r = [];
|
|
2890
2882
|
for (const s of e) {
|
|
2891
|
-
let
|
|
2892
|
-
t.preserveTrailingSpaces || (
|
|
2883
|
+
let a = s.join("");
|
|
2884
|
+
t.preserveTrailingSpaces || (a = a.replace(/\s+$/, "")), r.push(a);
|
|
2893
2885
|
}
|
|
2894
2886
|
const i = t.lineEnding === "crlf" ? `\r
|
|
2895
2887
|
` : `
|
|
@@ -2923,9 +2915,9 @@ class Ge extends N {
|
|
|
2923
2915
|
}
|
|
2924
2916
|
class j {
|
|
2925
2917
|
constructor() {
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2918
|
+
o(this, "dataExtractor");
|
|
2919
|
+
o(this, "contentGenerator");
|
|
2920
|
+
o(this, "fileHandler");
|
|
2929
2921
|
this.dataExtractor = new Pe(), this.contentGenerator = new Be(), this.fileHandler = new Ge();
|
|
2930
2922
|
}
|
|
2931
2923
|
/**
|
|
@@ -2972,7 +2964,7 @@ class j {
|
|
|
2972
2964
|
}
|
|
2973
2965
|
}
|
|
2974
2966
|
}
|
|
2975
|
-
class Ve extends
|
|
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"),
|
|
2988
|
-
return s.width = n, s.height =
|
|
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
|
-
|
|
2989
|
+
h
|
|
2998
2990
|
), s;
|
|
2999
2991
|
}
|
|
3000
2992
|
}
|
|
@@ -3017,10 +3009,10 @@ class ke {
|
|
|
3017
3009
|
*/
|
|
3018
3010
|
async generateImageBlob(e, t) {
|
|
3019
3011
|
return new Promise((r, i) => {
|
|
3020
|
-
const s = this.getMimeType(t.format),
|
|
3012
|
+
const s = this.getMimeType(t.format), a = (n) => {
|
|
3021
3013
|
n ? r(n) : i(new Error(`Failed to generate ${t.format.toUpperCase()} blob`));
|
|
3022
3014
|
};
|
|
3023
|
-
t.format === "png" ? e.toBlob(
|
|
3015
|
+
t.format === "png" ? e.toBlob(a, s) : e.toBlob(a, s, t.quality);
|
|
3024
3016
|
});
|
|
3025
3017
|
}
|
|
3026
3018
|
/**
|
|
@@ -3115,9 +3107,9 @@ class ze extends N {
|
|
|
3115
3107
|
}
|
|
3116
3108
|
class $e {
|
|
3117
3109
|
constructor() {
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3110
|
+
o(this, "dataExtractor");
|
|
3111
|
+
o(this, "contentGenerator");
|
|
3112
|
+
o(this, "fileHandler");
|
|
3121
3113
|
this.dataExtractor = new Ve(), this.contentGenerator = new ke(), this.fileHandler = new ze();
|
|
3122
3114
|
}
|
|
3123
3115
|
/**
|
|
@@ -3204,38 +3196,37 @@ class $e {
|
|
|
3204
3196
|
class I {
|
|
3205
3197
|
constructor(e = null, t = {}) {
|
|
3206
3198
|
/** The element to capture content from (optional for standalone mode) */
|
|
3207
|
-
|
|
3199
|
+
o(this, "captureSource");
|
|
3208
3200
|
/** Our WebGL overlay canvas manager */
|
|
3209
|
-
|
|
3201
|
+
o(this, "textmodeCanvas");
|
|
3210
3202
|
/** Core WebGL renderer */
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3203
|
+
o(this, "_renderer");
|
|
3204
|
+
o(this, "_canvasFramebuffer");
|
|
3205
|
+
o(this, "_font");
|
|
3206
|
+
o(this, "_grid");
|
|
3207
|
+
o(this, "resizeObserver");
|
|
3216
3208
|
// Auto-rendering properties
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3209
|
+
o(this, "_mode");
|
|
3210
|
+
o(this, "_frameRateLimit");
|
|
3211
|
+
o(this, "animationFrameId", null);
|
|
3212
|
+
o(this, "lastFrameTime", 0);
|
|
3213
|
+
o(this, "frameInterval");
|
|
3214
|
+
o(this, "_isLooping", !0);
|
|
3215
|
+
o(this, "_frameRate", 0);
|
|
3216
|
+
o(this, "lastRenderTime", 0);
|
|
3217
|
+
o(this, "_frameCount", 0);
|
|
3226
3218
|
// Frame rate measurement smoothing
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3219
|
+
o(this, "frameTimeHistory", []);
|
|
3220
|
+
o(this, "frameTimeHistorySize", 10);
|
|
3221
|
+
o(this, "_pipeline");
|
|
3222
|
+
o(this, "_isDisposed", !1);
|
|
3230
3223
|
// Standalone canvas properties
|
|
3231
|
-
|
|
3232
|
-
|
|
3224
|
+
o(this, "_standalone", !1);
|
|
3225
|
+
o(this, "_drawCallback", () => {
|
|
3233
3226
|
});
|
|
3234
|
-
|
|
3227
|
+
o(this, "_resizedCallback", () => {
|
|
3235
3228
|
});
|
|
3236
|
-
|
|
3237
|
-
a(this, "_isDestroyed", !1);
|
|
3238
|
-
a(this, "_windowResizeListener", null);
|
|
3229
|
+
o(this, "_windowResizeListener", null);
|
|
3239
3230
|
this.captureSource = e, this._standalone = e === null, this._mode = t.renderMode ?? "auto", this._frameRateLimit = t.frameRate ?? 60, this.frameInterval = 1e3 / this._frameRateLimit;
|
|
3240
3231
|
}
|
|
3241
3232
|
/**
|
|
@@ -3247,8 +3238,8 @@ class I {
|
|
|
3247
3238
|
static async create(e = null, t = {}) {
|
|
3248
3239
|
const r = new I(e, t), i = r._standalone ? t : void 0;
|
|
3249
3240
|
r.textmodeCanvas = new be(r.captureSource, r._standalone, i), r._renderer = new fe(r.textmodeCanvas.getWebGLContext());
|
|
3250
|
-
let s,
|
|
3251
|
-
r._standalone ? (s = t.width || 800,
|
|
3241
|
+
let s, a;
|
|
3242
|
+
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);
|
|
3252
3243
|
const n = r._font.maxGlyphDimensions;
|
|
3253
3244
|
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;
|
|
3254
3245
|
}
|
|
@@ -3477,11 +3468,7 @@ class I {
|
|
|
3477
3468
|
* ```
|
|
3478
3469
|
*/
|
|
3479
3470
|
render() {
|
|
3480
|
-
if (this.
|
|
3481
|
-
console.warn("Cannot render: Textmodifier instance has been destroyed");
|
|
3482
|
-
return;
|
|
3483
|
-
}
|
|
3484
|
-
if (this.measureFrameRate(), this._frameCount++, !this._canvasFramebuffer || !this._renderer || !this._pipeline) {
|
|
3471
|
+
if (this.measureFrameRate(), this._frameCount++, this._isDisposed) {
|
|
3485
3472
|
console.warn("Cannot render: Required resources have been disposed");
|
|
3486
3473
|
return;
|
|
3487
3474
|
}
|
|
@@ -3498,17 +3485,15 @@ class I {
|
|
|
3498
3485
|
* Start automatic rendering
|
|
3499
3486
|
*/
|
|
3500
3487
|
startAutoRendering() {
|
|
3501
|
-
if (this._mode !== "auto" ||
|
|
3488
|
+
if (this._mode !== "auto" || !this._isLooping) return;
|
|
3502
3489
|
this.lastFrameTime = performance.now();
|
|
3503
3490
|
const e = (t) => {
|
|
3504
|
-
if (this._isDestroyed)
|
|
3505
|
-
return;
|
|
3506
3491
|
if (!this._isLooping) {
|
|
3507
3492
|
this.animationFrameId = null;
|
|
3508
3493
|
return;
|
|
3509
3494
|
}
|
|
3510
3495
|
const r = t - this.lastFrameTime;
|
|
3511
|
-
r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval),
|
|
3496
|
+
r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), this._isLooping && (this.animationFrameId = requestAnimationFrame(e));
|
|
3512
3497
|
};
|
|
3513
3498
|
this.animationFrameId = requestAnimationFrame(e);
|
|
3514
3499
|
}
|
|
@@ -3517,7 +3502,6 @@ class I {
|
|
|
3517
3502
|
* Uses a rolling average for smoother frame rate reporting
|
|
3518
3503
|
*/
|
|
3519
3504
|
measureFrameRate() {
|
|
3520
|
-
if (this._isDestroyed) return;
|
|
3521
3505
|
const e = performance.now();
|
|
3522
3506
|
if (this.lastRenderTime > 0) {
|
|
3523
3507
|
const t = e - this.lastRenderTime;
|
|
@@ -3558,10 +3542,6 @@ class I {
|
|
|
3558
3542
|
* ```
|
|
3559
3543
|
*/
|
|
3560
3544
|
renderMode(e) {
|
|
3561
|
-
if (this._isDestroyed) {
|
|
3562
|
-
console.warn("Cannot change render mode: Textmodifier instance has been destroyed");
|
|
3563
|
-
return;
|
|
3564
|
-
}
|
|
3565
3545
|
this._mode !== e && (this.stopAutoRendering(), this._mode = e, e === "auto" && this._isLooping && this.startAutoRendering());
|
|
3566
3546
|
}
|
|
3567
3547
|
/**
|
|
@@ -3613,10 +3593,6 @@ class I {
|
|
|
3613
3593
|
* ```
|
|
3614
3594
|
*/
|
|
3615
3595
|
noLoop() {
|
|
3616
|
-
if (this._isDestroyed) {
|
|
3617
|
-
console.warn("Cannot stop loop: Textmodifier instance has been destroyed");
|
|
3618
|
-
return;
|
|
3619
|
-
}
|
|
3620
3596
|
this._isLooping && (this._isLooping = !1, this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null));
|
|
3621
3597
|
}
|
|
3622
3598
|
/**
|
|
@@ -3646,10 +3622,6 @@ class I {
|
|
|
3646
3622
|
* ```
|
|
3647
3623
|
*/
|
|
3648
3624
|
loop() {
|
|
3649
|
-
if (this._isDestroyed) {
|
|
3650
|
-
console.warn("Cannot start loop: Textmodifier instance has been destroyed");
|
|
3651
|
-
return;
|
|
3652
|
-
}
|
|
3653
3625
|
this._isLooping || (this._isLooping = !0, this._mode === "auto" && this.startAutoRendering());
|
|
3654
3626
|
}
|
|
3655
3627
|
/**
|
|
@@ -3681,7 +3653,7 @@ class I {
|
|
|
3681
3653
|
* ```
|
|
3682
3654
|
*/
|
|
3683
3655
|
isLooping() {
|
|
3684
|
-
return this.
|
|
3656
|
+
return this._mode === "auto" && this._isLooping;
|
|
3685
3657
|
}
|
|
3686
3658
|
/**
|
|
3687
3659
|
* Set the font size used for rendering.
|
|
@@ -4241,49 +4213,44 @@ class I {
|
|
|
4241
4213
|
* ```
|
|
4242
4214
|
*/
|
|
4243
4215
|
destroy() {
|
|
4244
|
-
this.
|
|
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 = () => {
|
|
4245
4217
|
}, this._resizedCallback = () => {
|
|
4246
|
-
}, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = [], this._isLooping = !1
|
|
4218
|
+
}, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = [], this._isLooping = !1;
|
|
4247
4219
|
}
|
|
4248
4220
|
/** Get the current grid object used for rendering. */
|
|
4249
4221
|
get grid() {
|
|
4250
|
-
if (this._isDestroyed)
|
|
4251
|
-
throw new Error("Cannot access grid: Textmodifier instance has been destroyed");
|
|
4252
4222
|
return this._grid;
|
|
4253
4223
|
}
|
|
4254
4224
|
/** Get the current font object used for rendering. */
|
|
4255
4225
|
get font() {
|
|
4256
|
-
if (this._isDestroyed)
|
|
4257
|
-
throw new Error("Cannot access font: Textmodifier instance has been destroyed");
|
|
4258
4226
|
return this._font;
|
|
4259
4227
|
}
|
|
4260
4228
|
/** Get the current rendering mode.*/
|
|
4261
4229
|
get mode() {
|
|
4262
|
-
if (this._isDestroyed)
|
|
4263
|
-
throw new Error("Cannot access mode: Textmodifier instance has been destroyed");
|
|
4264
4230
|
return this._mode;
|
|
4265
4231
|
}
|
|
4266
4232
|
/** Get the current textmode conversion pipeline. */
|
|
4267
4233
|
get pipeline() {
|
|
4268
|
-
if (this._isDestroyed)
|
|
4269
|
-
throw new Error("Cannot access pipeline: Textmodifier instance has been destroyed");
|
|
4270
4234
|
return this._pipeline;
|
|
4271
4235
|
}
|
|
4272
4236
|
/** Get the current frame count. */
|
|
4273
4237
|
get frameCount() {
|
|
4274
|
-
return this.
|
|
4238
|
+
return this._frameCount;
|
|
4239
|
+
}
|
|
4240
|
+
set frameCount(e) {
|
|
4241
|
+
this._frameCount = e;
|
|
4275
4242
|
}
|
|
4276
4243
|
/** Get the width of the canvas. */
|
|
4277
4244
|
get width() {
|
|
4278
|
-
return this.
|
|
4245
|
+
return this.textmodeCanvas.width;
|
|
4279
4246
|
}
|
|
4280
4247
|
/** Get the height of the canvas. */
|
|
4281
4248
|
get height() {
|
|
4282
|
-
return this.
|
|
4249
|
+
return this.textmodeCanvas.height;
|
|
4283
4250
|
}
|
|
4284
|
-
/** Check if
|
|
4285
|
-
get
|
|
4286
|
-
return this.
|
|
4251
|
+
/** Check if the instance has been disposed/destroyed. */
|
|
4252
|
+
get isDisposed() {
|
|
4253
|
+
return this._isDisposed;
|
|
4287
4254
|
}
|
|
4288
4255
|
}
|
|
4289
4256
|
class O {
|
|
@@ -4376,13 +4343,13 @@ class O {
|
|
|
4376
4343
|
* ```
|
|
4377
4344
|
*/
|
|
4378
4345
|
static get version() {
|
|
4379
|
-
return "0.1.4-beta.
|
|
4346
|
+
return "0.1.4-beta.3";
|
|
4380
4347
|
}
|
|
4381
4348
|
constructor() {
|
|
4382
4349
|
throw new Error("Textmode is a static class and cannot be instantiated.");
|
|
4383
4350
|
}
|
|
4384
4351
|
}
|
|
4385
|
-
const
|
|
4352
|
+
const Xe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4386
4353
|
__proto__: null
|
|
4387
4354
|
}, Symbol.toStringTag, { value: "Module" })), Ne = O.create, Oe = O.setErrorLevel, We = O.version;
|
|
4388
4355
|
export {
|
|
@@ -4392,10 +4359,10 @@ export {
|
|
|
4392
4359
|
xe as TextmodeFont,
|
|
4393
4360
|
ve as TextmodeGrid,
|
|
4394
4361
|
I as Textmodifier,
|
|
4395
|
-
|
|
4362
|
+
He as converters,
|
|
4396
4363
|
Ne as create,
|
|
4397
4364
|
O as default,
|
|
4398
|
-
|
|
4365
|
+
Xe as export,
|
|
4399
4366
|
Oe as setErrorLevel,
|
|
4400
4367
|
O as textmode,
|
|
4401
4368
|
We as version
|