textmode.js 0.1.4-beta.3 → 0.1.4-beta.5
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 +385 -407
- package/dist/textmode.esm.min.js +547 -569
- 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 +1 -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 +10 -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 n = (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
|
+
n(this, "originalError");
|
|
9
|
+
n(this, "context");
|
|
10
10
|
this.name = "TextmodeError", this.originalError = r, this.context = i;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
@@ -18,10 +18,10 @@ class F extends Error {
|
|
|
18
18
|
i += `
|
|
19
19
|
|
|
20
20
|
📋 Context:`;
|
|
21
|
-
for (const [s,
|
|
22
|
-
const
|
|
21
|
+
for (const [s, a] of Object.entries(r)) {
|
|
22
|
+
const o = F.formatValue(a);
|
|
23
23
|
i += `
|
|
24
|
-
- ${s}: ${
|
|
24
|
+
- ${s}: ${o}`;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
return i += `
|
|
@@ -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
|
|
49
|
+
var oe = /* @__PURE__ */ ((l) => (l[l.SILENT = 0] = "SILENT", l[l.WARNING = 1] = "WARNING", l[l.ERROR = 2] = "ERROR", l[l.THROW = 3] = "THROW", l))(oe || {});
|
|
50
50
|
const E = class E {
|
|
51
51
|
constructor() {
|
|
52
|
-
|
|
52
|
+
n(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
|
+
n(E, "_instance", null);
|
|
107
107
|
let $ = E;
|
|
108
108
|
const x = $.getInstance();
|
|
109
|
-
class
|
|
109
|
+
class ne {
|
|
110
110
|
constructor(e, t, r = t, i = {}) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
n(this, "gl");
|
|
112
|
+
n(this, "_framebuffer");
|
|
113
|
+
n(this, "_texture");
|
|
114
|
+
n(this, "_width");
|
|
115
|
+
n(this, "_height");
|
|
116
|
+
n(this, "options");
|
|
117
|
+
n(this, "previousState", null);
|
|
118
|
+
n(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), o = 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, o), 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), o = 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, o), [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), o = 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, o), 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
|
+
n(this, "gl");
|
|
231
|
+
n(this, "x");
|
|
232
|
+
n(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
|
+
n(this, "gl");
|
|
246
240
|
/** The vertex buffer containing position and texture coordinates */
|
|
247
|
-
|
|
241
|
+
n(this, "vertexBuffer");
|
|
248
242
|
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
249
|
-
|
|
243
|
+
n(this, "vertexCount", 6);
|
|
250
244
|
/** Bytes per vertex: depends on position format (vec2 vs vec3) */
|
|
251
|
-
|
|
245
|
+
n(this, "bytesPerVertex");
|
|
252
246
|
this.gl = e, this.bytesPerVertex = 16;
|
|
253
|
-
const
|
|
247
|
+
const a = e.getParameter(e.VIEWPORT), o = a[2], h = a[3], c = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, u = t / o * 2 - 1, d = (t + i) / o * 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
|
+
n(this, "width");
|
|
307
|
+
n(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
|
+
n(this, "gl");
|
|
337
331
|
/** The vertex buffer containing position and texture coordinates */
|
|
338
|
-
|
|
332
|
+
n(this, "vertexBuffer");
|
|
339
333
|
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
340
|
-
|
|
334
|
+
n(this, "vertexCount", 6);
|
|
341
335
|
/** Bytes per vertex: vec2+vec2 = 16 bytes */
|
|
342
|
-
|
|
336
|
+
n(this, "bytesPerVertex");
|
|
343
337
|
this.gl = e, this.bytesPerVertex = 16;
|
|
344
|
-
const
|
|
338
|
+
const o = e.getParameter(e.VIEWPORT), h = o[2], c = o[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, S = 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 = S / c * 2 - 1, V = D / c * 2 - 1, k = W / c * 2 - 1) : (B = 1 - A / c * 2, G = 1 - S / 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, o, 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)
|
|
@@ -427,13 +421,13 @@ class le {
|
|
|
427
421
|
0,
|
|
428
422
|
1,
|
|
429
423
|
// corner2 (start - perpendicular)
|
|
430
|
-
|
|
431
|
-
|
|
424
|
+
o,
|
|
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
|
+
n(this, "x2");
|
|
450
|
+
n(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
|
-
class
|
|
468
|
+
class y {
|
|
475
469
|
constructor(e, t, r) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
470
|
+
n(this, "gl");
|
|
471
|
+
n(this, "program");
|
|
472
|
+
n(this, "uniformLocations", /* @__PURE__ */ new Map());
|
|
473
|
+
n(this, "attributeLocations", /* @__PURE__ */ new Map());
|
|
474
|
+
n(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
|
*/
|
|
@@ -624,26 +612,26 @@ class T {
|
|
|
624
612
|
this.textureUnitCounter = 0;
|
|
625
613
|
}
|
|
626
614
|
}
|
|
627
|
-
var
|
|
615
|
+
var T = "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
|
+
n(this, "gl");
|
|
619
|
+
n(this, "imageShader");
|
|
620
|
+
n(this, "solidColorShader");
|
|
621
|
+
n(this, "currentShader", null);
|
|
634
622
|
// Fill state management - default: white fill enabled
|
|
635
|
-
|
|
636
|
-
|
|
623
|
+
n(this, "currentFillColor", [1, 1, 1, 1]);
|
|
624
|
+
n(this, "fillMode", !0);
|
|
637
625
|
// Stroke state management - default: black stroke enabled, weight 1
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
626
|
+
n(this, "currentStrokeColor", [0, 0, 0, 1]);
|
|
627
|
+
n(this, "currentStrokeWeight", 1);
|
|
628
|
+
n(this, "strokeMode", !0);
|
|
641
629
|
// Transformation state management
|
|
642
|
-
|
|
630
|
+
n(this, "currentRotation", 0);
|
|
643
631
|
// in degrees
|
|
644
632
|
// State stack for push/pop functionality
|
|
645
|
-
|
|
646
|
-
this.gl = e, this.imageShader = new
|
|
633
|
+
n(this, "stateStack", []);
|
|
634
|
+
this.gl = e, this.imageShader = new y(this.gl, T, ue), this.solidColorShader = new y(this.gl, T, 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
|
/**
|
|
649
637
|
* Set the current shader
|
|
@@ -744,7 +732,10 @@ class fe {
|
|
|
744
732
|
this.currentShader = null, this.stateStack = [], this.currentRotation = 0, this.fillMode = !0, this.strokeMode = !0, this.currentFillColor = [1, 1, 1, 1], this.currentStrokeColor = [0, 0, 0, 1], this.currentStrokeWeight = 1;
|
|
745
733
|
}
|
|
746
734
|
createShader(e, t) {
|
|
747
|
-
return new
|
|
735
|
+
return new y(this.gl, e, t);
|
|
736
|
+
}
|
|
737
|
+
createFilterShader(e) {
|
|
738
|
+
return new y(this.gl, T, e);
|
|
748
739
|
}
|
|
749
740
|
/**
|
|
750
741
|
* Set a uniform value for the current shader
|
|
@@ -756,18 +747,18 @@ class fe {
|
|
|
756
747
|
* Draw a rectangle with the current fill and/or stroke settings
|
|
757
748
|
*/
|
|
758
749
|
rect(e, t, r, i) {
|
|
759
|
-
const s = new
|
|
750
|
+
const s = new le(this.gl, e, t, r, i);
|
|
760
751
|
if (this.currentShader !== null) {
|
|
761
752
|
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",
|
|
753
|
+
const { centerX: d, centerY: f, radians: g, aspectRatio: _ } = this.calculateRotationParams(e, t, r, i);
|
|
754
|
+
this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", _);
|
|
764
755
|
} else
|
|
765
756
|
this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
|
|
766
757
|
s.renderFill(), this.currentShader = null;
|
|
767
758
|
return;
|
|
768
759
|
}
|
|
769
|
-
const
|
|
770
|
-
this.fillMode && (this.shader(
|
|
760
|
+
const a = this.solidColorShader, { centerX: o, centerY: h, radians: c, aspectRatio: u } = this.calculateRotationParams(e, t, r, i);
|
|
761
|
+
this.fillMode && (this.shader(a), this.setUniform("u_color", this.currentFillColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [o, 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", [o, h]), this.setUniform("u_aspectRatio", u), s.renderStroke(this.currentStrokeWeight)), this.currentShader = null;
|
|
771
762
|
}
|
|
772
763
|
/**
|
|
773
764
|
* Draw a line from (x1, y1) to (x2, y2) with the current stroke settings.
|
|
@@ -782,31 +773,31 @@ class fe {
|
|
|
782
773
|
const s = new ce(this.gl, e, t, r, i);
|
|
783
774
|
if (this.currentShader !== null) {
|
|
784
775
|
if (this.currentRotation !== 0) {
|
|
785
|
-
const
|
|
786
|
-
this.setUniform("u_rotation", R), this.setUniform("u_center", [w,
|
|
776
|
+
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: S } = this.calculateRotationParams(p - C / 2, b - v / 2, C, v);
|
|
777
|
+
this.setUniform("u_rotation", R), this.setUniform("u_center", [w, A]), this.setUniform("u_aspectRatio", S);
|
|
787
778
|
} else
|
|
788
779
|
this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
|
|
789
780
|
s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
|
|
790
781
|
return;
|
|
791
782
|
}
|
|
792
|
-
const
|
|
793
|
-
this.shader(
|
|
783
|
+
const a = this.solidColorShader, o = (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(o - c / 2, h - u / 2, c, u);
|
|
784
|
+
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
785
|
}
|
|
795
786
|
/**
|
|
796
787
|
* Calculate rotation parameters for built-in shaders (NDC coordinates)
|
|
797
788
|
*/
|
|
798
789
|
calculateRotationParams(e, t, r, i) {
|
|
799
|
-
const s = this.gl.getParameter(this.gl.VIEWPORT),
|
|
790
|
+
const s = this.gl.getParameter(this.gl.VIEWPORT), a = s[2], o = s[3], h = a / o, c = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING) !== null, u = e + r / 2, d = t + i / 2, f = u / a * 2 - 1;
|
|
800
791
|
let g;
|
|
801
|
-
c ? g = d /
|
|
802
|
-
const
|
|
803
|
-
return { centerX: f, centerY: g, radians:
|
|
792
|
+
c ? g = d / o * 2 - 1 : g = 1 - d / o * 2;
|
|
793
|
+
const _ = this.currentRotation * Math.PI / 180;
|
|
794
|
+
return { centerX: f, centerY: g, radians: _, aspectRatio: h };
|
|
804
795
|
}
|
|
805
796
|
/**
|
|
806
797
|
* Create a new framebuffer
|
|
807
798
|
*/
|
|
808
799
|
createFramebuffer(e, t, r = {}) {
|
|
809
|
-
return new
|
|
800
|
+
return new ne(this.gl, e, t, r);
|
|
810
801
|
}
|
|
811
802
|
/**
|
|
812
803
|
* Fill the current framebuffer with a solid color
|
|
@@ -837,31 +828,25 @@ class fe {
|
|
|
837
828
|
* This method is idempotent and safe to call multiple times.
|
|
838
829
|
*/
|
|
839
830
|
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;
|
|
831
|
+
this.imageShader.dispose(), this.solidColorShader.dispose(), this.imageShader = null, this.solidColorShader = null, this.currentShader = null, this.stateStack = [];
|
|
847
832
|
}
|
|
848
833
|
/**
|
|
849
834
|
* Render a framebuffer at a specific position with optional scaling
|
|
850
835
|
*/
|
|
851
836
|
image(e, t, r, i, s) {
|
|
852
837
|
this.shader(this.imageShader), this.setUniform("u_texture", e.texture);
|
|
853
|
-
const { centerX:
|
|
838
|
+
const { centerX: a, centerY: o, radians: h, aspectRatio: c } = this.calculateRotationParams(
|
|
854
839
|
t,
|
|
855
840
|
r,
|
|
856
841
|
i ?? e.width,
|
|
857
842
|
s ?? e.height
|
|
858
843
|
);
|
|
859
|
-
this.setUniform("u_rotation",
|
|
844
|
+
this.setUniform("u_rotation", h), this.setUniform("u_center", [a, o]), this.setUniform("u_aspectRatio", c), this.rect(t, r, i ?? e.width, s ?? e.height);
|
|
860
845
|
}
|
|
861
846
|
}
|
|
862
847
|
var m = {};
|
|
863
|
-
m.parse = function(
|
|
864
|
-
var e = function(s,
|
|
848
|
+
m.parse = function(l) {
|
|
849
|
+
var e = function(s, a, o, h) {
|
|
865
850
|
var c = m.T, u = {
|
|
866
851
|
cmap: c.cmap,
|
|
867
852
|
head: c.head,
|
|
@@ -870,119 +855,119 @@ m.parse = function(h) {
|
|
|
870
855
|
hmtx: c.hmtx,
|
|
871
856
|
loca: c.loca,
|
|
872
857
|
glyf: c.glyf
|
|
873
|
-
}, d = { _data: s, _index:
|
|
858
|
+
}, d = { _data: s, _index: a, _offset: o };
|
|
874
859
|
for (var f in u) {
|
|
875
|
-
var g = m.findTable(s, f,
|
|
860
|
+
var g = m.findTable(s, f, o);
|
|
876
861
|
if (g) {
|
|
877
|
-
var
|
|
878
|
-
|
|
862
|
+
var _ = g[0], p = h[_];
|
|
863
|
+
p == null && (p = u[f].parseTab(s, _, g[1], d)), d[f] = h[_] = p;
|
|
879
864
|
}
|
|
880
865
|
}
|
|
881
866
|
return d;
|
|
882
|
-
}, t = new Uint8Array(
|
|
867
|
+
}, t = new Uint8Array(l), r = {}, i = e(t, 0, 0, r);
|
|
883
868
|
return [i];
|
|
884
869
|
};
|
|
885
|
-
m.findTable = function(
|
|
886
|
-
for (var r = m.B, i = r.readUshort(
|
|
887
|
-
var
|
|
888
|
-
r.readUint(
|
|
889
|
-
var
|
|
890
|
-
if (
|
|
870
|
+
m.findTable = function(l, e, t) {
|
|
871
|
+
for (var r = m.B, i = r.readUshort(l, t + 4), s = t + 12, a = 0; a < i; a++) {
|
|
872
|
+
var o = r.readASCII(l, s, 4);
|
|
873
|
+
r.readUint(l, s + 4);
|
|
874
|
+
var h = r.readUint(l, s + 8), c = r.readUint(l, s + 12);
|
|
875
|
+
if (o == e) return [h, c];
|
|
891
876
|
s += 16;
|
|
892
877
|
}
|
|
893
878
|
return null;
|
|
894
879
|
};
|
|
895
880
|
m.T = {};
|
|
896
881
|
m.B = {
|
|
897
|
-
readShort: function(
|
|
882
|
+
readShort: function(l, e) {
|
|
898
883
|
var t = m.B.t.uint16;
|
|
899
|
-
return t[0] =
|
|
884
|
+
return t[0] = l[e] << 8 | l[e + 1], m.B.t.int16[0];
|
|
900
885
|
},
|
|
901
|
-
readUshort: function(
|
|
902
|
-
return
|
|
886
|
+
readUshort: function(l, e) {
|
|
887
|
+
return l[e] << 8 | l[e + 1];
|
|
903
888
|
},
|
|
904
|
-
readUshorts: function(
|
|
889
|
+
readUshorts: function(l, e, t) {
|
|
905
890
|
for (var r = [], i = 0; i < t; i++)
|
|
906
|
-
r.push(m.B.readUshort(
|
|
891
|
+
r.push(m.B.readUshort(l, e + i * 2));
|
|
907
892
|
return r;
|
|
908
893
|
},
|
|
909
|
-
readUint: function(
|
|
894
|
+
readUint: function(l, e) {
|
|
910
895
|
var t = m.B.t.uint8;
|
|
911
|
-
return t[3] =
|
|
896
|
+
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
897
|
},
|
|
913
|
-
readASCII: function(
|
|
914
|
-
for (var r = "", i = 0; i < t; i++) r += String.fromCharCode(
|
|
898
|
+
readASCII: function(l, e, t) {
|
|
899
|
+
for (var r = "", i = 0; i < t; i++) r += String.fromCharCode(l[e + i]);
|
|
915
900
|
return r;
|
|
916
901
|
},
|
|
917
902
|
// Simplified typed array buffer - only what's needed
|
|
918
903
|
t: function() {
|
|
919
|
-
var
|
|
904
|
+
var l = new ArrayBuffer(8);
|
|
920
905
|
return {
|
|
921
|
-
uint8: new Uint8Array(
|
|
922
|
-
int16: new Int16Array(
|
|
923
|
-
uint16: new Uint16Array(
|
|
924
|
-
uint32: new Uint32Array(
|
|
906
|
+
uint8: new Uint8Array(l),
|
|
907
|
+
int16: new Int16Array(l),
|
|
908
|
+
uint16: new Uint16Array(l),
|
|
909
|
+
uint32: new Uint32Array(l)
|
|
925
910
|
};
|
|
926
911
|
}()
|
|
927
912
|
};
|
|
928
913
|
m.T.cmap = {
|
|
929
|
-
parseTab: function(
|
|
914
|
+
parseTab: function(l, e, t) {
|
|
930
915
|
var r = { tables: [], ids: {}, off: e };
|
|
931
|
-
|
|
932
|
-
var i = m.B, s = i.readUshort,
|
|
933
|
-
s(
|
|
934
|
-
var
|
|
916
|
+
l = new Uint8Array(l.buffer, e, t), e = 0;
|
|
917
|
+
var i = m.B, s = i.readUshort, a = m.T.cmap;
|
|
918
|
+
s(l, e), e += 2;
|
|
919
|
+
var o = s(l, e);
|
|
935
920
|
e += 2;
|
|
936
|
-
for (var
|
|
937
|
-
var u = s(
|
|
921
|
+
for (var h = [], c = 0; c < o; c++) {
|
|
922
|
+
var u = s(l, e);
|
|
938
923
|
e += 2;
|
|
939
|
-
var d = s(
|
|
924
|
+
var d = s(l, e);
|
|
940
925
|
e += 2;
|
|
941
|
-
var f = i.readUint(
|
|
926
|
+
var f = i.readUint(l, e);
|
|
942
927
|
e += 4;
|
|
943
|
-
var g = "p" + u + "e" + d,
|
|
944
|
-
if (
|
|
945
|
-
|
|
946
|
-
var
|
|
947
|
-
|
|
948
|
-
var b =
|
|
949
|
-
b == 4 ?
|
|
928
|
+
var g = "p" + u + "e" + d, _ = h.indexOf(f);
|
|
929
|
+
if (_ == -1) {
|
|
930
|
+
_ = r.tables.length;
|
|
931
|
+
var p = {};
|
|
932
|
+
h.push(f);
|
|
933
|
+
var b = p.format = s(l, f);
|
|
934
|
+
b == 4 ? p = a.parse4(l, f, p) : b == 12 && (p = a.parse12(l, f, p)), r.tables.push(p);
|
|
950
935
|
}
|
|
951
|
-
r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] =
|
|
936
|
+
r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] = _;
|
|
952
937
|
}
|
|
953
938
|
return r;
|
|
954
939
|
},
|
|
955
|
-
parse4: function(
|
|
956
|
-
var r = m.B, i = r.readUshort, s = r.readUshorts,
|
|
940
|
+
parse4: function(l, e, t) {
|
|
941
|
+
var r = m.B, i = r.readUshort, s = r.readUshorts, a = e;
|
|
957
942
|
e += 2;
|
|
958
|
-
var
|
|
959
|
-
e += 2, i(
|
|
960
|
-
var
|
|
943
|
+
var o = i(l, e);
|
|
944
|
+
e += 2, i(l, e), e += 2;
|
|
945
|
+
var h = i(l, e);
|
|
961
946
|
e += 2;
|
|
962
|
-
var c =
|
|
963
|
-
t.searchRange = i(
|
|
947
|
+
var c = h >>> 1;
|
|
948
|
+
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
949
|
for (var u = 0; u < c; u++)
|
|
965
|
-
t.idDelta.push(r.readShort(
|
|
966
|
-
return t.idRangeOffset = s(
|
|
950
|
+
t.idDelta.push(r.readShort(l, e)), e += 2;
|
|
951
|
+
return t.idRangeOffset = s(l, e, c), e += c * 2, t.glyphIdArray = s(l, e, a + o - e >> 1), t;
|
|
967
952
|
},
|
|
968
|
-
parse12: function(
|
|
953
|
+
parse12: function(l, e, t) {
|
|
969
954
|
var r = m.B, i = r.readUint;
|
|
970
|
-
e += 4, i(
|
|
971
|
-
var s = i(
|
|
955
|
+
e += 4, i(l, e), e += 4, i(l, e), e += 4;
|
|
956
|
+
var s = i(l, e) * 3;
|
|
972
957
|
e += 4;
|
|
973
|
-
for (var
|
|
974
|
-
o
|
|
958
|
+
for (var a = t.groups = new Uint32Array(s), o = 0; o < s; o += 3)
|
|
959
|
+
a[o] = i(l, e + (o << 2)), a[o + 1] = i(l, e + (o << 2) + 4), a[o + 2] = i(l, e + (o << 2) + 8);
|
|
975
960
|
return t;
|
|
976
961
|
}
|
|
977
962
|
};
|
|
978
963
|
m.T.head = {
|
|
979
|
-
parseTab: function(
|
|
964
|
+
parseTab: function(l, e, t) {
|
|
980
965
|
var r = m.B, i = {};
|
|
981
|
-
return e += 18, i.unitsPerEm = r.readUshort(
|
|
966
|
+
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
967
|
}
|
|
983
968
|
};
|
|
984
969
|
m.T.hhea = {
|
|
985
|
-
parseTab: function(
|
|
970
|
+
parseTab: function(l, e, t) {
|
|
986
971
|
var r = m.B, i = {};
|
|
987
972
|
e += 4;
|
|
988
973
|
for (var s = [
|
|
@@ -1002,79 +987,79 @@ m.T.hhea = {
|
|
|
1002
987
|
"res3",
|
|
1003
988
|
"metricDataFormat",
|
|
1004
989
|
"numberOfHMetrics"
|
|
1005
|
-
],
|
|
1006
|
-
var
|
|
1007
|
-
i[
|
|
990
|
+
], a = 0; a < s.length; a++) {
|
|
991
|
+
var o = s[a], h = o == "advanceWidthMax" || o == "numberOfHMetrics" ? r.readUshort : r.readShort;
|
|
992
|
+
i[o] = h(l, e + a * 2);
|
|
1008
993
|
}
|
|
1009
994
|
return i;
|
|
1010
995
|
}
|
|
1011
996
|
};
|
|
1012
997
|
m.T.hmtx = {
|
|
1013
|
-
parseTab: function(
|
|
1014
|
-
for (var i = m.B, s = [],
|
|
1015
|
-
c = i.readUshort(
|
|
1016
|
-
for (; d <
|
|
1017
|
-
s.push(c),
|
|
1018
|
-
return { aWidth: s, lsBearing:
|
|
998
|
+
parseTab: function(l, e, t, r) {
|
|
999
|
+
for (var i = m.B, s = [], a = [], o = r.maxp.numGlyphs, h = r.hhea.numberOfHMetrics, c = 0, u = 0, d = 0; d < h; )
|
|
1000
|
+
c = i.readUshort(l, e + (d << 2)), u = i.readShort(l, e + (d << 2) + 2), s.push(c), a.push(u), d++;
|
|
1001
|
+
for (; d < o; )
|
|
1002
|
+
s.push(c), a.push(u), d++;
|
|
1003
|
+
return { aWidth: s, lsBearing: a };
|
|
1019
1004
|
}
|
|
1020
1005
|
};
|
|
1021
1006
|
m.T.maxp = {
|
|
1022
|
-
parseTab: function(
|
|
1007
|
+
parseTab: function(l, e, t) {
|
|
1023
1008
|
var r = m.B, i = r.readUshort, s = {};
|
|
1024
|
-
return r.readUint(
|
|
1009
|
+
return r.readUint(l, e), e += 4, s.numGlyphs = i(l, e), e += 2, s;
|
|
1025
1010
|
}
|
|
1026
1011
|
};
|
|
1027
1012
|
m.T.loca = {
|
|
1028
|
-
parseTab: function(
|
|
1029
|
-
var i = m.B, s = [],
|
|
1030
|
-
if (
|
|
1031
|
-
if (
|
|
1013
|
+
parseTab: function(l, e, t, r) {
|
|
1014
|
+
var i = m.B, s = [], a = r.head.indexToLocFormat, o = r.maxp.numGlyphs + 1;
|
|
1015
|
+
if (a == 0) for (var h = 0; h < o; h++) s.push(i.readUshort(l, e + (h << 1)) << 1);
|
|
1016
|
+
if (a == 1) for (var h = 0; h < o; h++) s.push(i.readUint(l, e + (h << 2)));
|
|
1032
1017
|
return s;
|
|
1033
1018
|
}
|
|
1034
1019
|
};
|
|
1035
1020
|
m.T.glyf = {
|
|
1036
|
-
parseTab: function(
|
|
1037
|
-
for (var i = [], s = r.maxp.numGlyphs,
|
|
1021
|
+
parseTab: function(l, e, t, r) {
|
|
1022
|
+
for (var i = [], s = r.maxp.numGlyphs, a = 0; a < s; a++) i.push(null);
|
|
1038
1023
|
return i;
|
|
1039
1024
|
},
|
|
1040
|
-
_parseGlyf: function(
|
|
1041
|
-
var t = m.B, r =
|
|
1025
|
+
_parseGlyf: function(l, e) {
|
|
1026
|
+
var t = m.B, r = l._data, i = l.loca;
|
|
1042
1027
|
if (i[e] == i[e + 1]) return null;
|
|
1043
|
-
var s = m.findTable(r, "glyf",
|
|
1044
|
-
if (
|
|
1045
|
-
if (
|
|
1046
|
-
|
|
1047
|
-
for (var
|
|
1048
|
-
|
|
1049
|
-
var
|
|
1050
|
-
if (s += 2, r.length - s <
|
|
1051
|
-
s +=
|
|
1052
|
-
var c =
|
|
1053
|
-
|
|
1054
|
-
for (var
|
|
1028
|
+
var s = m.findTable(r, "glyf", l._offset)[0] + i[e], a = {};
|
|
1029
|
+
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;
|
|
1030
|
+
if (a.noc > 0) {
|
|
1031
|
+
a.endPts = [];
|
|
1032
|
+
for (var o = 0; o < a.noc; o++)
|
|
1033
|
+
a.endPts.push(t.readUshort(r, s)), s += 2;
|
|
1034
|
+
var h = t.readUshort(r, s);
|
|
1035
|
+
if (s += 2, r.length - s < h) return null;
|
|
1036
|
+
s += h;
|
|
1037
|
+
var c = a.endPts[a.noc - 1] + 1;
|
|
1038
|
+
a.flags = [];
|
|
1039
|
+
for (var o = 0; o < c; o++) {
|
|
1055
1040
|
var u = r[s];
|
|
1056
|
-
if (s++,
|
|
1041
|
+
if (s++, a.flags.push(u), u & 8) {
|
|
1057
1042
|
var d = r[s];
|
|
1058
1043
|
s++;
|
|
1059
1044
|
for (var f = 0; f < d; f++)
|
|
1060
|
-
|
|
1045
|
+
a.flags.push(u), o++;
|
|
1061
1046
|
}
|
|
1062
1047
|
}
|
|
1063
|
-
|
|
1064
|
-
for (var
|
|
1065
|
-
var g = (
|
|
1066
|
-
g ? (
|
|
1048
|
+
a.xs = [];
|
|
1049
|
+
for (var o = 0; o < c; o++) {
|
|
1050
|
+
var g = (a.flags[o] & 2) != 0, _ = (a.flags[o] & 16) != 0;
|
|
1051
|
+
g ? (a.xs.push(_ ? r[s] : -r[s]), s++) : _ ? a.xs.push(0) : (a.xs.push(t.readShort(r, s)), s += 2);
|
|
1067
1052
|
}
|
|
1068
|
-
|
|
1069
|
-
for (var
|
|
1070
|
-
var g = (
|
|
1071
|
-
g ? (
|
|
1053
|
+
a.ys = [];
|
|
1054
|
+
for (var o = 0; o < c; o++) {
|
|
1055
|
+
var g = (a.flags[o] & 4) != 0, _ = (a.flags[o] & 32) != 0;
|
|
1056
|
+
g ? (a.ys.push(_ ? r[s] : -r[s]), s++) : _ ? a.ys.push(0) : (a.ys.push(t.readShort(r, s)), s += 2);
|
|
1072
1057
|
}
|
|
1073
|
-
for (var
|
|
1074
|
-
|
|
1058
|
+
for (var p = 0, b = 0, o = 0; o < c; o++)
|
|
1059
|
+
p += a.xs[o], b += a.ys[o], a.xs[o] = p, a.ys[o] = b;
|
|
1075
1060
|
} else
|
|
1076
|
-
|
|
1077
|
-
return
|
|
1061
|
+
a.parts = [];
|
|
1062
|
+
return a;
|
|
1078
1063
|
}
|
|
1079
1064
|
};
|
|
1080
1065
|
typeof module < "u" && module.exports ? module.exports = m : typeof window < "u" && (window.Typr = m);
|
|
@@ -1109,10 +1094,10 @@ class me {
|
|
|
1109
1094
|
for (let r = 0; r < e.startCount.length; r++) {
|
|
1110
1095
|
const i = e.startCount[r], s = e.endCount[r];
|
|
1111
1096
|
if (!(i === 65535 && s === 65535)) {
|
|
1112
|
-
for (let
|
|
1113
|
-
if (this._calculateGlyphIndexFormat4(e,
|
|
1114
|
-
const
|
|
1115
|
-
t.push(
|
|
1097
|
+
for (let a = i; a <= s; a++)
|
|
1098
|
+
if (this._calculateGlyphIndexFormat4(e, a, r) > 0) {
|
|
1099
|
+
const h = String.fromCodePoint(a);
|
|
1100
|
+
t.push(h);
|
|
1116
1101
|
}
|
|
1117
1102
|
}
|
|
1118
1103
|
}
|
|
@@ -1128,10 +1113,10 @@ class me {
|
|
|
1128
1113
|
if (!e.groups)
|
|
1129
1114
|
return t;
|
|
1130
1115
|
for (let r = 0; r < e.groups.length; r += 3) {
|
|
1131
|
-
const i = e.groups[r], s = e.groups[r + 1],
|
|
1132
|
-
for (let
|
|
1133
|
-
if (
|
|
1134
|
-
const c = String.fromCodePoint(
|
|
1116
|
+
const i = e.groups[r], s = e.groups[r + 1], a = e.groups[r + 2];
|
|
1117
|
+
for (let o = i; o <= s; o++)
|
|
1118
|
+
if (a + (o - i) > 0) {
|
|
1119
|
+
const c = String.fromCodePoint(o);
|
|
1135
1120
|
t.push(c);
|
|
1136
1121
|
}
|
|
1137
1122
|
}
|
|
@@ -1181,9 +1166,9 @@ class ge {
|
|
|
1181
1166
|
* @param renderer The WebGL renderer instance
|
|
1182
1167
|
*/
|
|
1183
1168
|
constructor(e) {
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1169
|
+
n(this, "_textureCanvas");
|
|
1170
|
+
n(this, "_textureContext");
|
|
1171
|
+
n(this, "_renderer");
|
|
1187
1172
|
this._renderer = e, this._textureCanvas = document.createElement("canvas"), this._textureContext = this._textureCanvas.getContext("2d", { willReadFrequently: !0, alpha: !1 });
|
|
1188
1173
|
}
|
|
1189
1174
|
/**
|
|
@@ -1195,13 +1180,13 @@ class ge {
|
|
|
1195
1180
|
* @returns Object containing framebuffer, columns, and rows
|
|
1196
1181
|
*/
|
|
1197
1182
|
createTextureAtlas(e, t, r, i) {
|
|
1198
|
-
const s = e.length,
|
|
1199
|
-
this._setupCanvas(
|
|
1200
|
-
const u = this._renderer.createFramebuffer(
|
|
1183
|
+
const s = e.length, a = Math.ceil(Math.sqrt(s)), o = Math.ceil(s / a), h = t.width * a, c = t.height * o;
|
|
1184
|
+
this._setupCanvas(h, c, r, i), this._renderCharactersToCanvas(e, t, a, r), this._applyBlackWhiteThreshold();
|
|
1185
|
+
const u = this._renderer.createFramebuffer(h, c, { filter: "nearest" });
|
|
1201
1186
|
return u.update(this._textureCanvas), {
|
|
1202
1187
|
framebuffer: u,
|
|
1203
|
-
columns:
|
|
1204
|
-
rows:
|
|
1188
|
+
columns: a,
|
|
1189
|
+
rows: o
|
|
1205
1190
|
};
|
|
1206
1191
|
}
|
|
1207
1192
|
/**
|
|
@@ -1225,7 +1210,7 @@ class ge {
|
|
|
1225
1210
|
*/
|
|
1226
1211
|
_renderCharactersToCanvas(e, t, r, i) {
|
|
1227
1212
|
for (let s = 0; s < e.length; s++) {
|
|
1228
|
-
const
|
|
1213
|
+
const a = s % r, o = Math.floor(s / r), h = a * t.width + t.width * 0.5, c = o * t.height + t.height * 0.5, u = Math.round(h - t.width * 0.5), d = Math.round(c - i * 0.5);
|
|
1229
1214
|
this._textureContext.fillText(e[s].character, u, d);
|
|
1230
1215
|
}
|
|
1231
1216
|
}
|
|
@@ -1238,19 +1223,19 @@ class ge {
|
|
|
1238
1223
|
_applyBlackWhiteThreshold(e = 128) {
|
|
1239
1224
|
const t = this._textureContext.getImageData(0, 0, this._textureCanvas.width, this._textureCanvas.height), r = t.data;
|
|
1240
1225
|
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],
|
|
1242
|
-
r[i] =
|
|
1226
|
+
const s = 0.299 * r[i] + 0.587 * r[i + 1] + 0.114 * r[i + 2], a = e + 32, o = s > a ? 255 : 0;
|
|
1227
|
+
r[i] = o, r[i + 1] = o, r[i + 2] = o;
|
|
1243
1228
|
}
|
|
1244
1229
|
this._textureContext.putImageData(t, 0, 0);
|
|
1245
1230
|
}
|
|
1246
1231
|
}
|
|
1247
|
-
class
|
|
1232
|
+
class pe {
|
|
1248
1233
|
/**
|
|
1249
1234
|
* Creates a new MetricsCalculation instance.
|
|
1250
1235
|
*/
|
|
1251
1236
|
constructor() {
|
|
1252
|
-
|
|
1253
|
-
|
|
1237
|
+
n(this, "_tempCanvas");
|
|
1238
|
+
n(this, "_tempContext");
|
|
1254
1239
|
this._tempCanvas = document.createElement("canvas"), this._tempContext = this._tempCanvas.getContext("2d");
|
|
1255
1240
|
}
|
|
1256
1241
|
/**
|
|
@@ -1264,9 +1249,9 @@ class _e {
|
|
|
1264
1249
|
calculateMaxGlyphDimensions(e, t, r) {
|
|
1265
1250
|
this._tempContext.font = `${t}px ${r}`;
|
|
1266
1251
|
let i = 0, s = 0;
|
|
1267
|
-
for (const
|
|
1268
|
-
const
|
|
1269
|
-
|
|
1252
|
+
for (const a of e) {
|
|
1253
|
+
const o = this._tempContext.measureText(a), h = o.width, c = o.actualBoundingBoxAscent + o.actualBoundingBoxDescent;
|
|
1254
|
+
h > 0 && (i = Math.max(i, h), s = Math.max(s, c));
|
|
1270
1255
|
}
|
|
1271
1256
|
return {
|
|
1272
1257
|
width: Math.ceil(i),
|
|
@@ -1274,7 +1259,7 @@ class _e {
|
|
|
1274
1259
|
};
|
|
1275
1260
|
}
|
|
1276
1261
|
}
|
|
1277
|
-
class
|
|
1262
|
+
class _e {
|
|
1278
1263
|
/**
|
|
1279
1264
|
* Creates TextmodeCharacter objects with unique color assignments.
|
|
1280
1265
|
* @param characters Array of character strings
|
|
@@ -1283,17 +1268,17 @@ class pe {
|
|
|
1283
1268
|
*/
|
|
1284
1269
|
createCharacterObjects(e, t) {
|
|
1285
1270
|
return e.map((r, i) => {
|
|
1286
|
-
const s = r.codePointAt(0) || 0,
|
|
1287
|
-
let
|
|
1271
|
+
const s = r.codePointAt(0) || 0, a = this._generateCharacterColor(i);
|
|
1272
|
+
let o = 0;
|
|
1288
1273
|
if (t.hmtx && t.hmtx.aWidth) {
|
|
1289
|
-
const
|
|
1290
|
-
|
|
1274
|
+
const h = this._getGlyphIndex(t, s);
|
|
1275
|
+
h > 0 && t.hmtx.aWidth[h] !== void 0 && (o = t.hmtx.aWidth[h]);
|
|
1291
1276
|
}
|
|
1292
1277
|
return {
|
|
1293
1278
|
character: r,
|
|
1294
1279
|
unicode: s,
|
|
1295
|
-
color:
|
|
1296
|
-
advanceWidth:
|
|
1280
|
+
color: a,
|
|
1281
|
+
advanceWidth: o
|
|
1297
1282
|
};
|
|
1298
1283
|
});
|
|
1299
1284
|
}
|
|
@@ -1314,11 +1299,11 @@ class pe {
|
|
|
1314
1299
|
if (i.idRangeOffset[s] === 0)
|
|
1315
1300
|
return t + i.idDelta[s] & 65535;
|
|
1316
1301
|
{
|
|
1317
|
-
const
|
|
1318
|
-
if (
|
|
1319
|
-
const
|
|
1320
|
-
if (
|
|
1321
|
-
return
|
|
1302
|
+
const a = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
|
|
1303
|
+
if (a >= 0 && a < i.glyphIdArray.length) {
|
|
1304
|
+
const o = i.glyphIdArray[a];
|
|
1305
|
+
if (o !== 0)
|
|
1306
|
+
return o + i.idDelta[s] & 65535;
|
|
1322
1307
|
}
|
|
1323
1308
|
}
|
|
1324
1309
|
}
|
|
@@ -1372,21 +1357,21 @@ class xe {
|
|
|
1372
1357
|
* @ignore
|
|
1373
1358
|
*/
|
|
1374
1359
|
constructor(e, t = 16) {
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1360
|
+
n(this, "_font");
|
|
1361
|
+
n(this, "_characters", []);
|
|
1362
|
+
n(this, "_fontFramebuffer");
|
|
1363
|
+
n(this, "_fontSize", 16);
|
|
1364
|
+
n(this, "_textureColumns", 0);
|
|
1365
|
+
n(this, "_textureRows", 0);
|
|
1366
|
+
n(this, "_maxGlyphDimensions", { width: 0, height: 0 });
|
|
1367
|
+
n(this, "_fontFace");
|
|
1368
|
+
n(this, "_fontFamilyName", "UrsaFont");
|
|
1384
1369
|
// Component classes
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new
|
|
1370
|
+
n(this, "_characterExtractor");
|
|
1371
|
+
n(this, "_textureAtlas");
|
|
1372
|
+
n(this, "_metricsCalculator");
|
|
1373
|
+
n(this, "_characterColorMapper");
|
|
1374
|
+
this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new pe(), this._characterColorMapper = new _e();
|
|
1390
1375
|
}
|
|
1391
1376
|
/**
|
|
1392
1377
|
* Initializes the font manager by loading the font and creating the texture atlas.
|
|
@@ -1529,13 +1514,7 @@ class xe {
|
|
|
1529
1514
|
* This method is idempotent and safe to call multiple times.
|
|
1530
1515
|
*/
|
|
1531
1516
|
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;
|
|
1517
|
+
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
1518
|
}
|
|
1540
1519
|
/** Returns the font size used for rendering. */
|
|
1541
1520
|
get fontSize() {
|
|
@@ -1556,25 +1535,25 @@ class ve {
|
|
|
1556
1535
|
*/
|
|
1557
1536
|
constructor(e, t, r) {
|
|
1558
1537
|
/** The number of columns in the grid. */
|
|
1559
|
-
|
|
1538
|
+
n(this, "_cols");
|
|
1560
1539
|
/** The number of rows in the grid. */
|
|
1561
|
-
|
|
1540
|
+
n(this, "_rows");
|
|
1562
1541
|
/** The total width of the grid in pixels. */
|
|
1563
|
-
|
|
1542
|
+
n(this, "_width");
|
|
1564
1543
|
/** The total height of the grid in pixels. */
|
|
1565
|
-
|
|
1544
|
+
n(this, "_height");
|
|
1566
1545
|
/** The offset to the outer canvas on the x-axis when centering the grid. */
|
|
1567
|
-
|
|
1546
|
+
n(this, "_offsetX");
|
|
1568
1547
|
/** The offset to the outer canvas on the y-axis when centering the grid. */
|
|
1569
|
-
|
|
1548
|
+
n(this, "_offsetY");
|
|
1570
1549
|
/** Whether the grid dimensions are fixed, or responsive based on the canvas dimensions. */
|
|
1571
|
-
|
|
1550
|
+
n(this, "_fixedDimensions", !1);
|
|
1572
1551
|
/** The canvas element used to determine the grid dimensions. */
|
|
1573
|
-
|
|
1552
|
+
n(this, "_canvas");
|
|
1574
1553
|
/** The width of each cell in the grid. */
|
|
1575
|
-
|
|
1554
|
+
n(this, "_cellWidth");
|
|
1576
1555
|
/** The height of each cell in the grid. */
|
|
1577
|
-
|
|
1556
|
+
n(this, "_cellHeight");
|
|
1578
1557
|
this._canvas = e, this._cellWidth = t, this._cellHeight = r, this.reset();
|
|
1579
1558
|
}
|
|
1580
1559
|
/**
|
|
@@ -1658,12 +1637,6 @@ class ve {
|
|
|
1658
1637
|
dispose() {
|
|
1659
1638
|
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
1639
|
}
|
|
1661
|
-
/**
|
|
1662
|
-
* Check if this TextmodeGrid has been disposed
|
|
1663
|
-
*/
|
|
1664
|
-
get isDisposed() {
|
|
1665
|
-
return this._canvas === null;
|
|
1666
|
-
}
|
|
1667
1640
|
/** Returns the number of columns in the grid. */
|
|
1668
1641
|
get cols() {
|
|
1669
1642
|
return this._cols;
|
|
@@ -1691,9 +1664,9 @@ class ve {
|
|
|
1691
1664
|
}
|
|
1692
1665
|
class be {
|
|
1693
1666
|
constructor(e, t = !1, r = {}) {
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1667
|
+
n(this, "_canvas");
|
|
1668
|
+
n(this, "captureSource");
|
|
1669
|
+
n(this, "_isStandalone");
|
|
1697
1670
|
this.captureSource = e, this._isStandalone = t, this._canvas = this.createCanvas(r.width, r.height);
|
|
1698
1671
|
}
|
|
1699
1672
|
createCanvas(e, t) {
|
|
@@ -1703,14 +1676,14 @@ class be {
|
|
|
1703
1676
|
r.width = e || 800, r.height = t || 600, document.body.appendChild(r);
|
|
1704
1677
|
else {
|
|
1705
1678
|
const s = this.captureSource.getBoundingClientRect();
|
|
1706
|
-
let
|
|
1679
|
+
let a = Math.round(s.width), o = Math.round(s.height);
|
|
1707
1680
|
if (this.captureSource instanceof HTMLVideoElement) {
|
|
1708
1681
|
const u = this.captureSource;
|
|
1709
|
-
(
|
|
1682
|
+
(a === 0 || o === 0) && u.videoWidth > 0 && u.videoHeight > 0 && (a = u.videoWidth, o = u.videoHeight);
|
|
1710
1683
|
}
|
|
1711
|
-
r.width =
|
|
1712
|
-
const
|
|
1713
|
-
let c = parseInt(
|
|
1684
|
+
r.width = a, r.height = o, r.style.position = "absolute", r.style.pointerEvents = "none";
|
|
1685
|
+
const h = window.getComputedStyle(this.captureSource);
|
|
1686
|
+
let c = parseInt(h.zIndex || "0", 10);
|
|
1714
1687
|
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
1688
|
}
|
|
1716
1689
|
return r;
|
|
@@ -1731,8 +1704,8 @@ class be {
|
|
|
1731
1704
|
const r = this.captureSource.getBoundingClientRect();
|
|
1732
1705
|
let i = Math.round(r.width), s = Math.round(r.height);
|
|
1733
1706
|
if (this.captureSource instanceof HTMLVideoElement) {
|
|
1734
|
-
const
|
|
1735
|
-
(i === 0 || s === 0) &&
|
|
1707
|
+
const a = this.captureSource;
|
|
1708
|
+
(i === 0 || s === 0) && a.videoWidth > 0 && a.videoHeight > 0 && (i = a.videoWidth, s = a.videoHeight);
|
|
1736
1709
|
}
|
|
1737
1710
|
this._canvas.width = i, this._canvas.height = s, this.positionOverlayCanvas(this._canvas);
|
|
1738
1711
|
}
|
|
@@ -1769,12 +1742,6 @@ class be {
|
|
|
1769
1742
|
}
|
|
1770
1743
|
this.captureSource = null;
|
|
1771
1744
|
}
|
|
1772
|
-
/**
|
|
1773
|
-
* Check if this TextmodeCanvas has been disposed
|
|
1774
|
-
*/
|
|
1775
|
-
get isDisposed() {
|
|
1776
|
-
return this._canvas === null;
|
|
1777
|
-
}
|
|
1778
1745
|
get canvas() {
|
|
1779
1746
|
return this._canvas;
|
|
1780
1747
|
}
|
|
@@ -1795,15 +1762,15 @@ class U {
|
|
|
1795
1762
|
* @ignore
|
|
1796
1763
|
*/
|
|
1797
1764
|
constructor(e, t, r, i = {}) {
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1765
|
+
n(this, "renderer");
|
|
1766
|
+
n(this, "fontManager");
|
|
1767
|
+
n(this, "grid");
|
|
1768
|
+
n(this, "_characterFramebuffer");
|
|
1769
|
+
n(this, "_primaryColorFramebuffer");
|
|
1770
|
+
n(this, "_secondaryColorFramebuffer");
|
|
1771
|
+
n(this, "_rotationFramebuffer");
|
|
1772
|
+
n(this, "_transformFramebuffer");
|
|
1773
|
+
n(this, "_options");
|
|
1807
1774
|
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
1775
|
}
|
|
1809
1776
|
/**
|
|
@@ -1837,13 +1804,7 @@ class U {
|
|
|
1837
1804
|
* This method is idempotent and safe to call multiple times.
|
|
1838
1805
|
*/
|
|
1839
1806
|
dispose() {
|
|
1840
|
-
this._characterFramebuffer
|
|
1841
|
-
}
|
|
1842
|
-
/**
|
|
1843
|
-
* Check if this converter has been disposed
|
|
1844
|
-
*/
|
|
1845
|
-
get isDisposed() {
|
|
1846
|
-
return this._characterFramebuffer === null;
|
|
1807
|
+
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
1808
|
}
|
|
1848
1809
|
/** Returns the framebuffer containing character data. */
|
|
1849
1810
|
get characterFramebuffer() {
|
|
@@ -1878,9 +1839,9 @@ class Ce {
|
|
|
1878
1839
|
*/
|
|
1879
1840
|
constructor(e, t) {
|
|
1880
1841
|
/** The framebuffer used to store the color palette. */
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1842
|
+
n(this, "_framebuffer");
|
|
1843
|
+
n(this, "_renderer");
|
|
1844
|
+
n(this, "_colors");
|
|
1884
1845
|
this._renderer = e, this._colors = t;
|
|
1885
1846
|
const r = Math.max(this._colors.length, 1);
|
|
1886
1847
|
this._framebuffer = this._renderer.createFramebuffer(r, 1), this._updateFramebuffer();
|
|
@@ -1894,8 +1855,8 @@ class Ce {
|
|
|
1894
1855
|
this._framebuffer.width !== e && this._framebuffer.resize(e, t);
|
|
1895
1856
|
const r = new Uint8Array(e * t * 4);
|
|
1896
1857
|
for (let i = 0; i < e; i++) {
|
|
1897
|
-
const s = i < this._colors.length ? this._colors[i] : [0, 0, 0],
|
|
1898
|
-
r[
|
|
1858
|
+
const s = i < this._colors.length ? this._colors[i] : [0, 0, 0], a = i * 4;
|
|
1859
|
+
r[a] = s[0], r[a + 1] = s[1], r[a + 2] = s[2], r[a + 3] = 255;
|
|
1899
1860
|
}
|
|
1900
1861
|
this._framebuffer.updatePixels(r, e, t);
|
|
1901
1862
|
}
|
|
@@ -1925,10 +1886,10 @@ class Ce {
|
|
|
1925
1886
|
return this._framebuffer.texture;
|
|
1926
1887
|
}
|
|
1927
1888
|
}
|
|
1928
|
-
class
|
|
1889
|
+
class H extends U {
|
|
1929
1890
|
constructor(t, r, i, s = {}) {
|
|
1930
1891
|
super(t, r, i, s);
|
|
1931
|
-
|
|
1892
|
+
n(this, "palette");
|
|
1932
1893
|
this.palette = new Ce(this.renderer, this.fontManager.getCharacterColors(" .:-=+*%@#"));
|
|
1933
1894
|
}
|
|
1934
1895
|
/**
|
|
@@ -1945,17 +1906,31 @@ class X extends U {
|
|
|
1945
1906
|
/**
|
|
1946
1907
|
* Sets the color of the characters affected by the converter.
|
|
1947
1908
|
* This is only used when `characterColorMode` is set to `'fixed'`.
|
|
1948
|
-
* @param r Red component (0-255).
|
|
1909
|
+
* @param r Red component (0-255) or hex string (e.g., '#FF0000', '#F00', 'FF0000', 'F00').
|
|
1949
1910
|
* @param g Green component (0-255).
|
|
1950
1911
|
* @param b Blue component (0-255).
|
|
1951
1912
|
* @param a Alpha component (0-255).
|
|
1952
1913
|
*/
|
|
1953
|
-
characterColor(t, r
|
|
1954
|
-
|
|
1955
|
-
|
|
1914
|
+
characterColor(t, r, i, s = 255) {
|
|
1915
|
+
let a, o, h, c;
|
|
1916
|
+
if (typeof t == "string") {
|
|
1917
|
+
const u = this.parseHexColor(t);
|
|
1918
|
+
if (!u) {
|
|
1919
|
+
x.validate(
|
|
1920
|
+
!1,
|
|
1921
|
+
"Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
|
|
1922
|
+
{ method: "characterColor", providedValue: t }
|
|
1923
|
+
);
|
|
1924
|
+
return;
|
|
1925
|
+
}
|
|
1926
|
+
[a, o, h, c] = u;
|
|
1927
|
+
} else if (a = t, o = r !== void 0 ? r : t, h = i !== void 0 ? i : t, c = s, !x.validate(
|
|
1928
|
+
[a, o, h, c].every((u) => u >= 0 && u <= 255),
|
|
1956
1929
|
"Character color values must be between 0 and 255",
|
|
1957
|
-
{ method: "characterColor", providedValues: { r:
|
|
1958
|
-
)
|
|
1930
|
+
{ method: "characterColor", providedValues: { r: a, g: o, b: h, a: c } }
|
|
1931
|
+
))
|
|
1932
|
+
return;
|
|
1933
|
+
this._options.characterColor = [a, o, h, c];
|
|
1959
1934
|
}
|
|
1960
1935
|
/**
|
|
1961
1936
|
* Sets the character color mode.
|
|
@@ -1973,17 +1948,31 @@ class X extends U {
|
|
|
1973
1948
|
/**
|
|
1974
1949
|
* Sets the cell color for all cells affected by the converter.
|
|
1975
1950
|
* This is only used when `cellColorMode` is set to `'fixed'`.
|
|
1976
|
-
* @param r Red component (0-255).
|
|
1951
|
+
* @param r Red component (0-255) or hex string (e.g., '#FF0000', '#F00', 'FF0000', 'F00').
|
|
1977
1952
|
* @param g Green component (0-255).
|
|
1978
1953
|
* @param b Blue component (0-255).
|
|
1979
1954
|
* @param a Alpha component (0-255).
|
|
1980
1955
|
*/
|
|
1981
|
-
cellColor(t, r
|
|
1982
|
-
|
|
1983
|
-
|
|
1956
|
+
cellColor(t, r, i, s = 255) {
|
|
1957
|
+
let a, o, h, c;
|
|
1958
|
+
if (typeof t == "string") {
|
|
1959
|
+
const u = this.parseHexColor(t);
|
|
1960
|
+
if (!u) {
|
|
1961
|
+
x.validate(
|
|
1962
|
+
!1,
|
|
1963
|
+
"Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
|
|
1964
|
+
{ method: "cellColor", providedValue: t }
|
|
1965
|
+
);
|
|
1966
|
+
return;
|
|
1967
|
+
}
|
|
1968
|
+
[a, o, h, c] = u;
|
|
1969
|
+
} else if (a = t, o = r !== void 0 ? r : t, h = i !== void 0 ? i : t, c = s, !x.validate(
|
|
1970
|
+
[a, o, h, c].every((u) => u >= 0 && u <= 255),
|
|
1984
1971
|
"Cell color values must be between 0 and 255",
|
|
1985
|
-
{ method: "cellColor", providedValues: { r:
|
|
1986
|
-
)
|
|
1972
|
+
{ method: "cellColor", providedValues: { r: a, g: o, b: h, a: c } }
|
|
1973
|
+
))
|
|
1974
|
+
return;
|
|
1975
|
+
this._options.cellColor = [a, o, h, c];
|
|
1987
1976
|
}
|
|
1988
1977
|
/**
|
|
1989
1978
|
* Sets the cell color mode.
|
|
@@ -2046,6 +2035,18 @@ class X extends U {
|
|
|
2046
2035
|
{ method: "flipVertically", providedValue: t }
|
|
2047
2036
|
) && (this._options.flipVertically = !!t);
|
|
2048
2037
|
}
|
|
2038
|
+
/**
|
|
2039
|
+
* Parses a hex color string and returns RGBA values.
|
|
2040
|
+
* @param hex Hex color string (e.g., '#FF0000', '#F00', 'FF0000', 'F00').
|
|
2041
|
+
* @returns RGBA array [r, g, b, a] or null if invalid.
|
|
2042
|
+
*/
|
|
2043
|
+
parseHexColor(t) {
|
|
2044
|
+
if (t = t.replace(/^#/, ""), !/^[0-9A-Fa-f]{3}$|^[0-9A-Fa-f]{6}$/.test(t))
|
|
2045
|
+
return null;
|
|
2046
|
+
t.length === 3 && (t = t.split("").map((a) => a + a).join(""));
|
|
2047
|
+
const r = parseInt(t.slice(0, 2), 16), i = parseInt(t.slice(2, 4), 16), s = parseInt(t.slice(4, 6), 16);
|
|
2048
|
+
return [r, i, s, 255];
|
|
2049
|
+
}
|
|
2049
2050
|
}
|
|
2050
2051
|
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
2052
|
const Re = {
|
|
@@ -2072,7 +2073,7 @@ const Re = {
|
|
|
2072
2073
|
/** Range of brightness values to map to ASCII characters */
|
|
2073
2074
|
brightnessRange: [0, 255]
|
|
2074
2075
|
};
|
|
2075
|
-
class L extends
|
|
2076
|
+
class L extends H {
|
|
2076
2077
|
/**
|
|
2077
2078
|
* Creates a new TextmodeBrightnessConverter instance.
|
|
2078
2079
|
* @param renderer Renderer instance for texture creation
|
|
@@ -2082,16 +2083,16 @@ class L extends X {
|
|
|
2082
2083
|
*/
|
|
2083
2084
|
constructor(t, r, i) {
|
|
2084
2085
|
super(t, r, i, { ...Re });
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
this.sampleShader = new
|
|
2086
|
+
n(this, "sampleShader");
|
|
2087
|
+
n(this, "colorFillShader");
|
|
2088
|
+
n(this, "charMappingShader");
|
|
2089
|
+
n(this, "transformFillShader");
|
|
2090
|
+
n(this, "rotationFillShader");
|
|
2091
|
+
n(this, "sampleFramebuffer");
|
|
2092
|
+
this.sampleShader = new y(t.context, T, Fe), this.colorFillShader = new y(t.context, T, we), this.transformFillShader = new y(t.context, T, ye), this.rotationFillShader = new y(t.context, T, Te), this.charMappingShader = new y(t.context, T, Se), this.sampleFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
|
|
2092
2093
|
}
|
|
2093
2094
|
convert(t) {
|
|
2094
|
-
this.sampleFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.sampleShader), this.renderer.setUniform("u_sketchTexture", t), this.renderer.setUniform("u_gridCellDimensions", [this.grid.cols, this.grid.rows]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this.sampleFramebuffer.end(), this._primaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.characterColor), this.renderer.setUniform("u_useFixedColor", this._options.characterColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._primaryColorFramebuffer.end(), this._secondaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.cellColor), this.renderer.setUniform("u_useFixedColor", this._options.cellColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._secondaryColorFramebuffer.end(), this._transformFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.transformFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_invert", this._options.invert), this.renderer.setUniform("u_flipHorizontally", this._options.flipHorizontally), this.renderer.setUniform("u_flipVertically", this._options.flipVertically), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._transformFramebuffer.end(), this._rotationFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.rotationFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_rotationColor", this._options.rotation), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._rotationFramebuffer.end(), this._characterFramebuffer.begin(), this.renderer.clear(0, 0, 0, 0), this.renderer.shader(this.charMappingShader), this.renderer.setUniform("u_colorSampleFramebuffer", this.sampleFramebuffer.texture), this.renderer.setUniform("u_charPaletteTexture", this.palette.texture), this.renderer.setUniform("u_charPaletteSize", [this.palette.colors.length, 1]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._characterFramebuffer.end();
|
|
2095
|
+
this.sampleFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.sampleShader), this.renderer.setUniform("u_sketchTexture", t), this.renderer.setUniform("u_gridCellDimensions", [this.grid.cols, this.grid.rows]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this.sampleFramebuffer.end(), console.log("this.options.characterColor:", this._options.characterColor), this._primaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.characterColor), this.renderer.setUniform("u_useFixedColor", this._options.characterColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._primaryColorFramebuffer.end(), this._secondaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.cellColor), this.renderer.setUniform("u_useFixedColor", this._options.cellColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._secondaryColorFramebuffer.end(), this._transformFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.transformFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_invert", this._options.invert), this.renderer.setUniform("u_flipHorizontally", this._options.flipHorizontally), this.renderer.setUniform("u_flipVertically", this._options.flipVertically), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._transformFramebuffer.end(), this._rotationFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.rotationFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_rotationColor", this._options.rotation), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._rotationFramebuffer.end(), this._characterFramebuffer.begin(), this.renderer.clear(0, 0, 0, 0), this.renderer.shader(this.charMappingShader), this.renderer.setUniform("u_colorSampleFramebuffer", this.sampleFramebuffer.texture), this.renderer.setUniform("u_charPaletteTexture", this.palette.texture), this.renderer.setUniform("u_charPaletteSize", [this.palette.colors.length, 1]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._characterFramebuffer.end();
|
|
2095
2096
|
}
|
|
2096
2097
|
resize() {
|
|
2097
2098
|
super.resize(), this.sampleFramebuffer.resize(this.grid.cols, this.grid.rows);
|
|
@@ -2111,11 +2112,11 @@ class L extends X {
|
|
|
2111
2112
|
) && (this._options.brightnessRange = t);
|
|
2112
2113
|
}
|
|
2113
2114
|
}
|
|
2114
|
-
const
|
|
2115
|
+
const He = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2115
2116
|
__proto__: null,
|
|
2116
2117
|
TextmodeBrightnessConverter: L,
|
|
2117
2118
|
TextmodeConverter: U,
|
|
2118
|
-
TextmodeFeatureConverter:
|
|
2119
|
+
TextmodeFeatureConverter: H
|
|
2119
2120
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2120
2121
|
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
2122
|
class Ue {
|
|
@@ -2127,18 +2128,18 @@ class Ue {
|
|
|
2127
2128
|
* @ignore
|
|
2128
2129
|
*/
|
|
2129
2130
|
constructor(e, t, r) {
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
this.renderer = e, this.font = t, this.grid = r, this._asciiShader = this.renderer.createShader(
|
|
2131
|
+
n(this, "renderer");
|
|
2132
|
+
n(this, "font");
|
|
2133
|
+
n(this, "grid");
|
|
2134
|
+
n(this, "converters");
|
|
2135
|
+
n(this, "_resultFramebuffer");
|
|
2136
|
+
n(this, "_asciiShader");
|
|
2137
|
+
n(this, "_characterFramebuffer");
|
|
2138
|
+
n(this, "_primaryColorFramebuffer");
|
|
2139
|
+
n(this, "_secondaryColorFramebuffer");
|
|
2140
|
+
n(this, "_rotationFramebuffer");
|
|
2141
|
+
n(this, "_transformFramebuffer");
|
|
2142
|
+
this.renderer = e, this.font = t, this.grid = r, this._asciiShader = this.renderer.createShader(T, Ee), this.converters = [
|
|
2142
2143
|
{ name: "brightness", converter: new L(e, t, r) },
|
|
2143
2144
|
{ name: "custom", converter: new U(e, t, r) }
|
|
2144
2145
|
], this._characterFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._primaryColorFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._secondaryColorFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._rotationFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._transformFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._resultFramebuffer = this.renderer.createFramebuffer(this.grid.width, this.grid.height);
|
|
@@ -2151,13 +2152,13 @@ class Ue {
|
|
|
2151
2152
|
render(e) {
|
|
2152
2153
|
for (const r of this.converters) {
|
|
2153
2154
|
const i = r.converter;
|
|
2154
|
-
i.options.enabled && i instanceof
|
|
2155
|
+
i.options.enabled && i instanceof H && i.convert(e);
|
|
2155
2156
|
}
|
|
2156
2157
|
const t = (r, i) => {
|
|
2157
2158
|
r.begin(), this.renderer.clear();
|
|
2158
2159
|
for (const s of this.converters) {
|
|
2159
|
-
const
|
|
2160
|
-
|
|
2160
|
+
const a = s.converter;
|
|
2161
|
+
a.options.enabled && this.renderer.image(i(a), 0, 0);
|
|
2161
2162
|
}
|
|
2162
2163
|
r.end();
|
|
2163
2164
|
};
|
|
@@ -2273,14 +2274,8 @@ class Ue {
|
|
|
2273
2274
|
*/
|
|
2274
2275
|
dispose() {
|
|
2275
2276
|
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;
|
|
2277
|
+
e.converter.dispose();
|
|
2278
|
+
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
2279
|
}
|
|
2285
2280
|
/** Returns the character framebuffer containing the combined result of all converters. */
|
|
2286
2281
|
get characterFramebuffer() {
|
|
@@ -2303,20 +2298,20 @@ class Ue {
|
|
|
2303
2298
|
return this._transformFramebuffer;
|
|
2304
2299
|
}
|
|
2305
2300
|
}
|
|
2306
|
-
class
|
|
2301
|
+
class X {
|
|
2307
2302
|
/**
|
|
2308
2303
|
* Extracts pixel data from all framebuffers needed for export
|
|
2309
2304
|
* @param pipeline The conversion pipeline containing framebuffers
|
|
2310
2305
|
* @returns Object containing all pixel data arrays
|
|
2311
2306
|
*/
|
|
2312
2307
|
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(),
|
|
2308
|
+
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, o = t == null ? void 0 : t.rotationFramebuffer;
|
|
2309
|
+
return r == null || r.loadPixels(), i == null || i.loadPixels(), s == null || s.loadPixels(), a == null || a.loadPixels(), o == null || o.loadPixels(), {
|
|
2315
2310
|
characterPixels: (r == null ? void 0 : r.pixels) || new Uint8Array(0),
|
|
2316
2311
|
primaryColorPixels: (i == null ? void 0 : i.pixels) || new Uint8Array(0),
|
|
2317
2312
|
secondaryColorPixels: (s == null ? void 0 : s.pixels) || new Uint8Array(0),
|
|
2318
|
-
transformPixels: (
|
|
2319
|
-
rotationPixels: (
|
|
2313
|
+
transformPixels: (a == null ? void 0 : a.pixels) || new Uint8Array(0),
|
|
2314
|
+
rotationPixels: (o == null ? void 0 : o.pixels) || new Uint8Array(0)
|
|
2320
2315
|
};
|
|
2321
2316
|
}
|
|
2322
2317
|
/**
|
|
@@ -2363,8 +2358,8 @@ class N {
|
|
|
2363
2358
|
*/
|
|
2364
2359
|
downloadFile(e, t, r) {
|
|
2365
2360
|
try {
|
|
2366
|
-
const i = this.createBlob(e, r), s = URL.createObjectURL(i),
|
|
2367
|
-
|
|
2361
|
+
const i = this.createBlob(e, r), s = URL.createObjectURL(i), a = document.createElement("a");
|
|
2362
|
+
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
2363
|
} catch (i) {
|
|
2369
2364
|
throw console.error("Failed to download file:", i), new Error(`File download failed: ${i instanceof Error ? i.message : "Unknown error"}`);
|
|
2370
2365
|
}
|
|
@@ -2402,7 +2397,7 @@ class N {
|
|
|
2402
2397
|
return `'textmode-export'-${this.generateTimestamp()}`;
|
|
2403
2398
|
}
|
|
2404
2399
|
}
|
|
2405
|
-
class
|
|
2400
|
+
class Ae extends X {
|
|
2406
2401
|
/**
|
|
2407
2402
|
* Extracts transform data from transform pixels
|
|
2408
2403
|
* @param transformPixels Transform framebuffer pixels
|
|
@@ -2411,10 +2406,10 @@ class De extends H {
|
|
|
2411
2406
|
* @returns Transform data object
|
|
2412
2407
|
*/
|
|
2413
2408
|
extractTransformData(e, t, r) {
|
|
2414
|
-
const i = e[r], s = e[r + 1],
|
|
2409
|
+
const i = e[r], s = e[r + 1], a = e[r + 2], o = 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
2410
|
return {
|
|
2416
|
-
isInverted:
|
|
2417
|
-
flipHorizontal:
|
|
2411
|
+
isInverted: o,
|
|
2412
|
+
flipHorizontal: h,
|
|
2418
2413
|
flipVertical: c,
|
|
2419
2414
|
rotation: g
|
|
2420
2415
|
};
|
|
@@ -2445,24 +2440,24 @@ class De extends H {
|
|
|
2445
2440
|
const r = [];
|
|
2446
2441
|
let i = 0;
|
|
2447
2442
|
for (let s = 0; s < t.rows; s++)
|
|
2448
|
-
for (let
|
|
2449
|
-
const
|
|
2443
|
+
for (let a = 0; a < t.cols; a++) {
|
|
2444
|
+
const o = i * 4, h = this.getCharacterIndex(
|
|
2450
2445
|
e.characterPixels,
|
|
2451
|
-
|
|
2446
|
+
o
|
|
2452
2447
|
);
|
|
2453
|
-
let c = this.pixelsToRGBA(e.primaryColorPixels,
|
|
2448
|
+
let c = this.pixelsToRGBA(e.primaryColorPixels, o), u = this.pixelsToRGBA(e.secondaryColorPixels, o);
|
|
2454
2449
|
const d = this.extractTransformData(
|
|
2455
2450
|
e.transformPixels,
|
|
2456
2451
|
e.rotationPixels,
|
|
2457
|
-
|
|
2452
|
+
o
|
|
2458
2453
|
);
|
|
2459
2454
|
if (d.isInverted) {
|
|
2460
2455
|
const g = c;
|
|
2461
2456
|
c = u, u = g;
|
|
2462
2457
|
}
|
|
2463
|
-
const f = this.calculateCellPosition(
|
|
2458
|
+
const f = this.calculateCellPosition(a, s, t);
|
|
2464
2459
|
r.push({
|
|
2465
|
-
charIndex:
|
|
2460
|
+
charIndex: h,
|
|
2466
2461
|
primaryColor: c,
|
|
2467
2462
|
secondaryColor: u,
|
|
2468
2463
|
transform: d,
|
|
@@ -2472,7 +2467,7 @@ class De extends H {
|
|
|
2472
2467
|
return r;
|
|
2473
2468
|
}
|
|
2474
2469
|
}
|
|
2475
|
-
class
|
|
2470
|
+
class Me {
|
|
2476
2471
|
/**
|
|
2477
2472
|
* Gets the glyph index for a given Unicode code point in a Typr.js font
|
|
2478
2473
|
* @param fontData The Typr.js font data
|
|
@@ -2489,11 +2484,11 @@ class Ae {
|
|
|
2489
2484
|
if (i.idRangeOffset[s] === 0)
|
|
2490
2485
|
return t + i.idDelta[s] & 65535;
|
|
2491
2486
|
{
|
|
2492
|
-
const
|
|
2493
|
-
if (
|
|
2494
|
-
const
|
|
2495
|
-
if (
|
|
2496
|
-
return
|
|
2487
|
+
const a = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
|
|
2488
|
+
if (a >= 0 && a < i.glyphIdArray.length) {
|
|
2489
|
+
const o = i.glyphIdArray[a];
|
|
2490
|
+
if (o !== 0)
|
|
2491
|
+
return o + i.idDelta[s] & 65535;
|
|
2497
2492
|
}
|
|
2498
2493
|
}
|
|
2499
2494
|
}
|
|
@@ -2522,15 +2517,15 @@ class Ae {
|
|
|
2522
2517
|
createGlyphPath(e, t, r, i, s) {
|
|
2523
2518
|
if (!t || !t.xs || t.xs.length === 0)
|
|
2524
2519
|
return this.createEmptyPath();
|
|
2525
|
-
const
|
|
2520
|
+
const a = s / e.head.unitsPerEm;
|
|
2526
2521
|
return {
|
|
2527
2522
|
getBoundingBox: () => ({
|
|
2528
|
-
x1: r + t.xMin *
|
|
2529
|
-
y1: i + -t.yMax *
|
|
2530
|
-
x2: r + t.xMax *
|
|
2531
|
-
y2: i + -t.yMin *
|
|
2523
|
+
x1: r + t.xMin * a,
|
|
2524
|
+
y1: i + -t.yMax * a,
|
|
2525
|
+
x2: r + t.xMax * a,
|
|
2526
|
+
y2: i + -t.yMin * a
|
|
2532
2527
|
}),
|
|
2533
|
-
toSVG: () => this.glyphToSVGPath(t, r, i,
|
|
2528
|
+
toSVG: () => this.glyphToSVGPath(t, r, i, a)
|
|
2534
2529
|
};
|
|
2535
2530
|
}
|
|
2536
2531
|
/**
|
|
@@ -2543,29 +2538,29 @@ class Ae {
|
|
|
2543
2538
|
*/
|
|
2544
2539
|
glyphToSVGPath(e, t, r, i) {
|
|
2545
2540
|
if (!e || !e.xs) return "";
|
|
2546
|
-
const { xs: s, ys:
|
|
2547
|
-
if (!s || !
|
|
2541
|
+
const { xs: s, ys: a, endPts: o, flags: h } = e;
|
|
2542
|
+
if (!s || !a || !o || !h) return "";
|
|
2548
2543
|
let c = "", u = 0;
|
|
2549
|
-
for (let d = 0; d <
|
|
2550
|
-
const f =
|
|
2544
|
+
for (let d = 0; d < o.length; d++) {
|
|
2545
|
+
const f = o[d];
|
|
2551
2546
|
if (!(f < u)) {
|
|
2552
2547
|
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)}`,
|
|
2548
|
+
const g = t + s[u] * i, _ = r - a[u] * i;
|
|
2549
|
+
c += `M${g.toFixed(2)},${_.toFixed(2)}`;
|
|
2550
|
+
let p = u + 1;
|
|
2551
|
+
for (; p <= f; )
|
|
2552
|
+
if ((h[p] & 1) !== 0) {
|
|
2553
|
+
const C = t + s[p] * i, v = r - a[p] * i;
|
|
2554
|
+
c += `L${C.toFixed(2)},${v.toFixed(2)}`, p++;
|
|
2560
2555
|
} else {
|
|
2561
|
-
const C = t + s[
|
|
2562
|
-
let w =
|
|
2563
|
-
if ((
|
|
2564
|
-
const R = t + s[w] * i,
|
|
2565
|
-
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${R.toFixed(2)},${
|
|
2556
|
+
const C = t + s[p] * i, v = r - a[p] * i;
|
|
2557
|
+
let w = p + 1 > f ? u : p + 1;
|
|
2558
|
+
if ((h[w] & 1) !== 0) {
|
|
2559
|
+
const R = t + s[w] * i, S = r - a[w] * i;
|
|
2560
|
+
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${R.toFixed(2)},${S.toFixed(2)}`, p = w + 1;
|
|
2566
2561
|
} else {
|
|
2567
|
-
const R = t + s[w] * i,
|
|
2568
|
-
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${P.toFixed(2)},${
|
|
2562
|
+
const R = t + s[w] * i, S = r - a[w] * i, P = (C + R) / 2, D = (v + S) / 2;
|
|
2563
|
+
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${P.toFixed(2)},${D.toFixed(2)}`, p = w;
|
|
2569
2564
|
}
|
|
2570
2565
|
}
|
|
2571
2566
|
c += "Z";
|
|
@@ -2586,18 +2581,18 @@ class Ae {
|
|
|
2586
2581
|
*/
|
|
2587
2582
|
generateCharacterPath(e, t, r, i, s) {
|
|
2588
2583
|
try {
|
|
2589
|
-
const
|
|
2590
|
-
if (
|
|
2584
|
+
const a = e.codePointAt(0) || 0, o = this.getGlyphIndex(t, a);
|
|
2585
|
+
if (o === 0)
|
|
2591
2586
|
return this.createEmptyPath();
|
|
2592
|
-
let
|
|
2587
|
+
let h = null;
|
|
2593
2588
|
try {
|
|
2594
|
-
t.glyf && t.glyf[
|
|
2589
|
+
t.glyf && t.glyf[o] !== null ? h = t.glyf[o] : m && m.T && m.T.glyf && m.T.glyf._parseGlyf && (h = m.T.glyf._parseGlyf(t, o), t.glyf && h && (t.glyf[o] = h));
|
|
2595
2590
|
} catch (c) {
|
|
2596
|
-
console.warn(`Failed to parse glyph ${
|
|
2591
|
+
console.warn(`Failed to parse glyph ${o}:`, c);
|
|
2597
2592
|
}
|
|
2598
|
-
return
|
|
2599
|
-
} catch (
|
|
2600
|
-
return console.warn(`Failed to generate path for character "${e}":`,
|
|
2593
|
+
return h ? this.createGlyphPath(t, h, r, i, s) : this.createEmptyPath();
|
|
2594
|
+
} catch (a) {
|
|
2595
|
+
return console.warn(`Failed to generate path for character "${e}":`, a), this.createEmptyPath();
|
|
2601
2596
|
}
|
|
2602
2597
|
}
|
|
2603
2598
|
/**
|
|
@@ -2612,19 +2607,19 @@ class Ae {
|
|
|
2612
2607
|
* @param advanceWidth Character advance width
|
|
2613
2608
|
* @returns SVG path data string or null if generation fails
|
|
2614
2609
|
*/
|
|
2615
|
-
generatePositionedCharacterPath(e, t, r, i, s,
|
|
2610
|
+
generatePositionedCharacterPath(e, t, r, i, s, a, o, h) {
|
|
2616
2611
|
try {
|
|
2617
|
-
const c =
|
|
2618
|
-
return this.generateCharacterPath(e, t, d, f,
|
|
2612
|
+
const c = o / t.head.unitsPerEm, u = h * c, d = r + (s - u) / 2, f = i + (a + o * 0.7) / 2;
|
|
2613
|
+
return this.generateCharacterPath(e, t, d, f, o).toSVG() || null;
|
|
2619
2614
|
} catch (c) {
|
|
2620
2615
|
return console.warn(`Failed to generate positioned character path for "${e}":`, c), null;
|
|
2621
2616
|
}
|
|
2622
2617
|
}
|
|
2623
2618
|
}
|
|
2624
|
-
class
|
|
2619
|
+
class De {
|
|
2625
2620
|
constructor() {
|
|
2626
|
-
|
|
2627
|
-
this.pathGenerator = new
|
|
2621
|
+
n(this, "pathGenerator");
|
|
2622
|
+
this.pathGenerator = new Me();
|
|
2628
2623
|
}
|
|
2629
2624
|
/**
|
|
2630
2625
|
* Generates the SVG header with metadata
|
|
@@ -2676,12 +2671,12 @@ class Me {
|
|
|
2676
2671
|
* @returns Transform attribute string or empty string
|
|
2677
2672
|
*/
|
|
2678
2673
|
generateTransformAttribute(e, t) {
|
|
2679
|
-
const { transform: r, position: i } = e, s = i.cellX + t.cellWidth / 2,
|
|
2674
|
+
const { transform: r, position: i } = e, s = i.cellX + t.cellWidth / 2, a = i.cellY + t.cellHeight / 2, o = [];
|
|
2680
2675
|
if (r.flipHorizontal || r.flipVertical) {
|
|
2681
|
-
const
|
|
2682
|
-
|
|
2676
|
+
const h = r.flipHorizontal ? -1 : 1, c = r.flipVertical ? -1 : 1;
|
|
2677
|
+
o.push(`translate(${s} ${a})`), o.push(`scale(${h} ${c})`), o.push(`translate(${-s} ${-a})`);
|
|
2683
2678
|
}
|
|
2684
|
-
return r.rotation &&
|
|
2679
|
+
return r.rotation && o.push(`rotate(${r.rotation} ${s} ${a})`), o.length ? ` transform="${o.join(" ")}"` : "";
|
|
2685
2680
|
}
|
|
2686
2681
|
/**
|
|
2687
2682
|
* Generates background rectangle for a cell
|
|
@@ -2710,7 +2705,7 @@ class Me {
|
|
|
2710
2705
|
const s = r.characters[e.charIndex];
|
|
2711
2706
|
if (!s)
|
|
2712
2707
|
return "";
|
|
2713
|
-
const
|
|
2708
|
+
const a = this.pathGenerator.generatePositionedCharacterPath(
|
|
2714
2709
|
s.character,
|
|
2715
2710
|
r.font,
|
|
2716
2711
|
e.position.cellX,
|
|
@@ -2720,12 +2715,12 @@ class Me {
|
|
|
2720
2715
|
r.fontSize,
|
|
2721
2716
|
s.advanceWidth
|
|
2722
2717
|
);
|
|
2723
|
-
if (!
|
|
2718
|
+
if (!a)
|
|
2724
2719
|
return "";
|
|
2725
|
-
const
|
|
2720
|
+
const o = this.rgbaToColorString(e.primaryColor);
|
|
2726
2721
|
return i.drawMode === "stroke" ? `
|
|
2727
|
-
<path id="${`path-${e.charIndex}-${e.position.cellX}-${e.position.cellY}`.replace(/\./g, "-")}" d="${
|
|
2728
|
-
<path d="${
|
|
2722
|
+
<path id="${`path-${e.charIndex}-${e.position.cellX}-${e.position.cellY}`.replace(/\./g, "-")}" d="${a}" stroke="${o}" stroke-width="${i.strokeWidth}" fill="none" />` : `
|
|
2723
|
+
<path d="${a}" fill="${o}" />`;
|
|
2729
2724
|
}
|
|
2730
2725
|
/**
|
|
2731
2726
|
* Generates complete SVG content for a single cell
|
|
@@ -2738,10 +2733,10 @@ class Me {
|
|
|
2738
2733
|
generateCellContent(e, t, r, i) {
|
|
2739
2734
|
let s = "";
|
|
2740
2735
|
s += this.generateCellBackground(e, t, i);
|
|
2741
|
-
const
|
|
2742
|
-
return
|
|
2743
|
-
<g${
|
|
2744
|
-
</g>`) : s +=
|
|
2736
|
+
const a = this.generateTransformAttribute(e, t), o = this.generateCharacterPath(e, t, r, i);
|
|
2737
|
+
return o && (a ? (s += `
|
|
2738
|
+
<g${a}>`, s += o, s += `
|
|
2739
|
+
</g>`) : s += o), s;
|
|
2745
2740
|
}
|
|
2746
2741
|
/**
|
|
2747
2742
|
* Generates the complete SVG content from cell data
|
|
@@ -2755,8 +2750,8 @@ class Me {
|
|
|
2755
2750
|
let s = this.generateSVGHeader(t);
|
|
2756
2751
|
s += this.generateBackground(t, i), s += `
|
|
2757
2752
|
<g id="ascii-cells">`;
|
|
2758
|
-
for (const
|
|
2759
|
-
s += this.generateCellContent(
|
|
2753
|
+
for (const a of e)
|
|
2754
|
+
s += this.generateCellContent(a, t, r, i);
|
|
2760
2755
|
return s += this.generateSVGFooter(), s;
|
|
2761
2756
|
}
|
|
2762
2757
|
/**
|
|
@@ -2801,10 +2796,10 @@ class Ie extends N {
|
|
|
2801
2796
|
}
|
|
2802
2797
|
class Y {
|
|
2803
2798
|
constructor() {
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
this.dataExtractor = new
|
|
2799
|
+
n(this, "dataExtractor");
|
|
2800
|
+
n(this, "contentGenerator");
|
|
2801
|
+
n(this, "fileHandler");
|
|
2802
|
+
this.dataExtractor = new Ae(), this.contentGenerator = new De(), this.fileHandler = new Ie();
|
|
2808
2803
|
}
|
|
2809
2804
|
/**
|
|
2810
2805
|
* Applies default values to SVG export options
|
|
@@ -2829,13 +2824,13 @@ class Y {
|
|
|
2829
2824
|
const r = this.applyDefaultOptions(t), i = this.dataExtractor.extractFramebufferData(e.pipeline), s = this.dataExtractor.extractSVGCellData(
|
|
2830
2825
|
i,
|
|
2831
2826
|
e.grid
|
|
2832
|
-
),
|
|
2827
|
+
), a = this.contentGenerator.generateSVGContent(
|
|
2833
2828
|
s,
|
|
2834
2829
|
e.grid,
|
|
2835
2830
|
e.font,
|
|
2836
2831
|
r
|
|
2837
2832
|
);
|
|
2838
|
-
return this.contentGenerator.optimizeSVGContent(
|
|
2833
|
+
return this.contentGenerator.optimizeSVGContent(a);
|
|
2839
2834
|
}
|
|
2840
2835
|
/**
|
|
2841
2836
|
* Exports SVG content to a downloadable file
|
|
@@ -2851,7 +2846,7 @@ class Y {
|
|
|
2851
2846
|
}
|
|
2852
2847
|
}
|
|
2853
2848
|
}
|
|
2854
|
-
class Pe extends
|
|
2849
|
+
class Pe extends X {
|
|
2855
2850
|
/**
|
|
2856
2851
|
* Extracts character data for TXT generation
|
|
2857
2852
|
* @param framebufferData Framebuffer pixel data
|
|
@@ -2861,17 +2856,17 @@ class Pe extends H {
|
|
|
2861
2856
|
* @returns 2D array of characters (rows x columns)
|
|
2862
2857
|
*/
|
|
2863
2858
|
extractCharacterGrid(e, t, r, i = " ") {
|
|
2864
|
-
var
|
|
2859
|
+
var o;
|
|
2865
2860
|
const s = [];
|
|
2866
|
-
let
|
|
2867
|
-
for (let
|
|
2861
|
+
let a = 0;
|
|
2862
|
+
for (let h = 0; h < t.rows; h++) {
|
|
2868
2863
|
const c = [];
|
|
2869
2864
|
for (let u = 0; u < t.cols; u++) {
|
|
2870
|
-
const d =
|
|
2865
|
+
const d = a * 4, f = this.getCharacterIndex(
|
|
2871
2866
|
e.characterPixels,
|
|
2872
2867
|
d
|
|
2873
|
-
), g = ((
|
|
2874
|
-
c.push(g),
|
|
2868
|
+
), g = ((o = r.characters[f]) == null ? void 0 : o.character) || i;
|
|
2869
|
+
c.push(g), a++;
|
|
2875
2870
|
}
|
|
2876
2871
|
s.push(c);
|
|
2877
2872
|
}
|
|
@@ -2888,8 +2883,8 @@ class Be {
|
|
|
2888
2883
|
generateTXTContent(e, t) {
|
|
2889
2884
|
const r = [];
|
|
2890
2885
|
for (const s of e) {
|
|
2891
|
-
let
|
|
2892
|
-
t.preserveTrailingSpaces || (
|
|
2886
|
+
let a = s.join("");
|
|
2887
|
+
t.preserveTrailingSpaces || (a = a.replace(/\s+$/, "")), r.push(a);
|
|
2893
2888
|
}
|
|
2894
2889
|
const i = t.lineEnding === "crlf" ? `\r
|
|
2895
2890
|
` : `
|
|
@@ -2923,9 +2918,9 @@ class Ge extends N {
|
|
|
2923
2918
|
}
|
|
2924
2919
|
class j {
|
|
2925
2920
|
constructor() {
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2921
|
+
n(this, "dataExtractor");
|
|
2922
|
+
n(this, "contentGenerator");
|
|
2923
|
+
n(this, "fileHandler");
|
|
2929
2924
|
this.dataExtractor = new Pe(), this.contentGenerator = new Be(), this.fileHandler = new Ge();
|
|
2930
2925
|
}
|
|
2931
2926
|
/**
|
|
@@ -2972,7 +2967,7 @@ class j {
|
|
|
2972
2967
|
}
|
|
2973
2968
|
}
|
|
2974
2969
|
}
|
|
2975
|
-
class Ve extends
|
|
2970
|
+
class Ve extends X {
|
|
2976
2971
|
/**
|
|
2977
2972
|
* Captures the current state of the textmode canvas as image data
|
|
2978
2973
|
* @param canvas The canvas data containing the rendered textmode graphics
|
|
@@ -2984,8 +2979,8 @@ class Ve extends H {
|
|
|
2984
2979
|
const i = e.canvas;
|
|
2985
2980
|
if (t === 1 && r === "transparent")
|
|
2986
2981
|
return i;
|
|
2987
|
-
const s = document.createElement("canvas"),
|
|
2988
|
-
return s.width =
|
|
2982
|
+
const s = document.createElement("canvas"), a = s.getContext("2d"), o = Math.round(i.width * t), h = Math.round(i.height * t);
|
|
2983
|
+
return s.width = o, s.height = h, r !== "transparent" && (a.fillStyle = r, a.fillRect(0, 0, o, h)), a.imageSmoothingEnabled = !1, a.drawImage(
|
|
2989
2984
|
i,
|
|
2990
2985
|
0,
|
|
2991
2986
|
0,
|
|
@@ -2993,8 +2988,8 @@ class Ve extends H {
|
|
|
2993
2988
|
i.height,
|
|
2994
2989
|
0,
|
|
2995
2990
|
0,
|
|
2996
|
-
|
|
2997
|
-
|
|
2991
|
+
o,
|
|
2992
|
+
h
|
|
2998
2993
|
), s;
|
|
2999
2994
|
}
|
|
3000
2995
|
}
|
|
@@ -3017,10 +3012,10 @@ class ke {
|
|
|
3017
3012
|
*/
|
|
3018
3013
|
async generateImageBlob(e, t) {
|
|
3019
3014
|
return new Promise((r, i) => {
|
|
3020
|
-
const s = this.getMimeType(t.format),
|
|
3021
|
-
|
|
3015
|
+
const s = this.getMimeType(t.format), a = (o) => {
|
|
3016
|
+
o ? r(o) : i(new Error(`Failed to generate ${t.format.toUpperCase()} blob`));
|
|
3022
3017
|
};
|
|
3023
|
-
t.format === "png" ? e.toBlob(
|
|
3018
|
+
t.format === "png" ? e.toBlob(a, s) : e.toBlob(a, s, t.quality);
|
|
3024
3019
|
});
|
|
3025
3020
|
}
|
|
3026
3021
|
/**
|
|
@@ -3115,9 +3110,9 @@ class ze extends N {
|
|
|
3115
3110
|
}
|
|
3116
3111
|
class $e {
|
|
3117
3112
|
constructor() {
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3113
|
+
n(this, "dataExtractor");
|
|
3114
|
+
n(this, "contentGenerator");
|
|
3115
|
+
n(this, "fileHandler");
|
|
3121
3116
|
this.dataExtractor = new Ve(), this.contentGenerator = new ke(), this.fileHandler = new ze();
|
|
3122
3117
|
}
|
|
3123
3118
|
/**
|
|
@@ -3204,38 +3199,37 @@ class $e {
|
|
|
3204
3199
|
class I {
|
|
3205
3200
|
constructor(e = null, t = {}) {
|
|
3206
3201
|
/** The element to capture content from (optional for standalone mode) */
|
|
3207
|
-
|
|
3202
|
+
n(this, "captureSource");
|
|
3208
3203
|
/** Our WebGL overlay canvas manager */
|
|
3209
|
-
|
|
3204
|
+
n(this, "textmodeCanvas");
|
|
3210
3205
|
/** Core WebGL renderer */
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3206
|
+
n(this, "_renderer");
|
|
3207
|
+
n(this, "_canvasFramebuffer");
|
|
3208
|
+
n(this, "_font");
|
|
3209
|
+
n(this, "_grid");
|
|
3210
|
+
n(this, "resizeObserver");
|
|
3216
3211
|
// Auto-rendering properties
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3212
|
+
n(this, "_mode");
|
|
3213
|
+
n(this, "_frameRateLimit");
|
|
3214
|
+
n(this, "animationFrameId", null);
|
|
3215
|
+
n(this, "lastFrameTime", 0);
|
|
3216
|
+
n(this, "frameInterval");
|
|
3217
|
+
n(this, "_isLooping", !0);
|
|
3218
|
+
n(this, "_frameRate", 0);
|
|
3219
|
+
n(this, "lastRenderTime", 0);
|
|
3220
|
+
n(this, "_frameCount", 0);
|
|
3226
3221
|
// Frame rate measurement smoothing
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3222
|
+
n(this, "frameTimeHistory", []);
|
|
3223
|
+
n(this, "frameTimeHistorySize", 10);
|
|
3224
|
+
n(this, "_pipeline");
|
|
3225
|
+
n(this, "_isDisposed", !1);
|
|
3230
3226
|
// Standalone canvas properties
|
|
3231
|
-
|
|
3232
|
-
|
|
3227
|
+
n(this, "_standalone", !1);
|
|
3228
|
+
n(this, "_drawCallback", () => {
|
|
3233
3229
|
});
|
|
3234
|
-
|
|
3230
|
+
n(this, "_resizedCallback", () => {
|
|
3235
3231
|
});
|
|
3236
|
-
|
|
3237
|
-
a(this, "_isDestroyed", !1);
|
|
3238
|
-
a(this, "_windowResizeListener", null);
|
|
3232
|
+
n(this, "_windowResizeListener", null);
|
|
3239
3233
|
this.captureSource = e, this._standalone = e === null, this._mode = t.renderMode ?? "auto", this._frameRateLimit = t.frameRate ?? 60, this.frameInterval = 1e3 / this._frameRateLimit;
|
|
3240
3234
|
}
|
|
3241
3235
|
/**
|
|
@@ -3247,10 +3241,10 @@ class I {
|
|
|
3247
3241
|
static async create(e = null, t = {}) {
|
|
3248
3242
|
const r = new I(e, t), i = r._standalone ? t : void 0;
|
|
3249
3243
|
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,
|
|
3252
|
-
const
|
|
3253
|
-
return r._grid = new ve(r.textmodeCanvas.canvas,
|
|
3244
|
+
let s, a;
|
|
3245
|
+
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);
|
|
3246
|
+
const o = r._font.maxGlyphDimensions;
|
|
3247
|
+
return r._grid = new ve(r.textmodeCanvas.canvas, o.width, o.height), r._pipeline = new Ue(r._renderer, r._font, r._grid), r.setupEventListeners(), r.startAutoRendering(), r;
|
|
3254
3248
|
}
|
|
3255
3249
|
setupEventListeners() {
|
|
3256
3250
|
this._windowResizeListener = () => {
|
|
@@ -3477,11 +3471,7 @@ class I {
|
|
|
3477
3471
|
* ```
|
|
3478
3472
|
*/
|
|
3479
3473
|
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) {
|
|
3474
|
+
if (this.measureFrameRate(), this._frameCount++, this._isDisposed) {
|
|
3485
3475
|
console.warn("Cannot render: Required resources have been disposed");
|
|
3486
3476
|
return;
|
|
3487
3477
|
}
|
|
@@ -3498,17 +3488,15 @@ class I {
|
|
|
3498
3488
|
* Start automatic rendering
|
|
3499
3489
|
*/
|
|
3500
3490
|
startAutoRendering() {
|
|
3501
|
-
if (this._mode !== "auto" ||
|
|
3491
|
+
if (this._mode !== "auto" || !this._isLooping) return;
|
|
3502
3492
|
this.lastFrameTime = performance.now();
|
|
3503
3493
|
const e = (t) => {
|
|
3504
|
-
if (this._isDestroyed)
|
|
3505
|
-
return;
|
|
3506
3494
|
if (!this._isLooping) {
|
|
3507
3495
|
this.animationFrameId = null;
|
|
3508
3496
|
return;
|
|
3509
3497
|
}
|
|
3510
3498
|
const r = t - this.lastFrameTime;
|
|
3511
|
-
r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval),
|
|
3499
|
+
r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), this._isLooping && (this.animationFrameId = requestAnimationFrame(e));
|
|
3512
3500
|
};
|
|
3513
3501
|
this.animationFrameId = requestAnimationFrame(e);
|
|
3514
3502
|
}
|
|
@@ -3517,7 +3505,6 @@ class I {
|
|
|
3517
3505
|
* Uses a rolling average for smoother frame rate reporting
|
|
3518
3506
|
*/
|
|
3519
3507
|
measureFrameRate() {
|
|
3520
|
-
if (this._isDestroyed) return;
|
|
3521
3508
|
const e = performance.now();
|
|
3522
3509
|
if (this.lastRenderTime > 0) {
|
|
3523
3510
|
const t = e - this.lastRenderTime;
|
|
@@ -3558,10 +3545,6 @@ class I {
|
|
|
3558
3545
|
* ```
|
|
3559
3546
|
*/
|
|
3560
3547
|
renderMode(e) {
|
|
3561
|
-
if (this._isDestroyed) {
|
|
3562
|
-
console.warn("Cannot change render mode: Textmodifier instance has been destroyed");
|
|
3563
|
-
return;
|
|
3564
|
-
}
|
|
3565
3548
|
this._mode !== e && (this.stopAutoRendering(), this._mode = e, e === "auto" && this._isLooping && this.startAutoRendering());
|
|
3566
3549
|
}
|
|
3567
3550
|
/**
|
|
@@ -3613,10 +3596,6 @@ class I {
|
|
|
3613
3596
|
* ```
|
|
3614
3597
|
*/
|
|
3615
3598
|
noLoop() {
|
|
3616
|
-
if (this._isDestroyed) {
|
|
3617
|
-
console.warn("Cannot stop loop: Textmodifier instance has been destroyed");
|
|
3618
|
-
return;
|
|
3619
|
-
}
|
|
3620
3599
|
this._isLooping && (this._isLooping = !1, this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null));
|
|
3621
3600
|
}
|
|
3622
3601
|
/**
|
|
@@ -3646,10 +3625,6 @@ class I {
|
|
|
3646
3625
|
* ```
|
|
3647
3626
|
*/
|
|
3648
3627
|
loop() {
|
|
3649
|
-
if (this._isDestroyed) {
|
|
3650
|
-
console.warn("Cannot start loop: Textmodifier instance has been destroyed");
|
|
3651
|
-
return;
|
|
3652
|
-
}
|
|
3653
3628
|
this._isLooping || (this._isLooping = !0, this._mode === "auto" && this.startAutoRendering());
|
|
3654
3629
|
}
|
|
3655
3630
|
/**
|
|
@@ -3681,7 +3656,7 @@ class I {
|
|
|
3681
3656
|
* ```
|
|
3682
3657
|
*/
|
|
3683
3658
|
isLooping() {
|
|
3684
|
-
return this.
|
|
3659
|
+
return this._mode === "auto" && this._isLooping;
|
|
3685
3660
|
}
|
|
3686
3661
|
/**
|
|
3687
3662
|
* Set the font size used for rendering.
|
|
@@ -4198,6 +4173,14 @@ class I {
|
|
|
4198
4173
|
createShader(e, t) {
|
|
4199
4174
|
return this._renderer.createShader(e, t);
|
|
4200
4175
|
}
|
|
4176
|
+
/**
|
|
4177
|
+
* Create a filter shader program from a fragment source code.
|
|
4178
|
+
* @param fragmentSource The GLSL source code for the fragment shader.
|
|
4179
|
+
* @returns The created filter shader program for use in `textmode.js`.
|
|
4180
|
+
*/
|
|
4181
|
+
createFilterShader(e) {
|
|
4182
|
+
return this._renderer.createFilterShader(e);
|
|
4183
|
+
}
|
|
4201
4184
|
/**
|
|
4202
4185
|
* Set the current shader for rendering.
|
|
4203
4186
|
* @param shader The shader program to use for rendering.
|
|
@@ -4241,49 +4224,44 @@ class I {
|
|
|
4241
4224
|
* ```
|
|
4242
4225
|
*/
|
|
4243
4226
|
destroy() {
|
|
4244
|
-
this.
|
|
4227
|
+
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
4228
|
}, this._resizedCallback = () => {
|
|
4246
|
-
}, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = [], this._isLooping = !1
|
|
4229
|
+
}, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = [], this._isLooping = !1;
|
|
4247
4230
|
}
|
|
4248
4231
|
/** Get the current grid object used for rendering. */
|
|
4249
4232
|
get grid() {
|
|
4250
|
-
if (this._isDestroyed)
|
|
4251
|
-
throw new Error("Cannot access grid: Textmodifier instance has been destroyed");
|
|
4252
4233
|
return this._grid;
|
|
4253
4234
|
}
|
|
4254
4235
|
/** Get the current font object used for rendering. */
|
|
4255
4236
|
get font() {
|
|
4256
|
-
if (this._isDestroyed)
|
|
4257
|
-
throw new Error("Cannot access font: Textmodifier instance has been destroyed");
|
|
4258
4237
|
return this._font;
|
|
4259
4238
|
}
|
|
4260
4239
|
/** Get the current rendering mode.*/
|
|
4261
4240
|
get mode() {
|
|
4262
|
-
if (this._isDestroyed)
|
|
4263
|
-
throw new Error("Cannot access mode: Textmodifier instance has been destroyed");
|
|
4264
4241
|
return this._mode;
|
|
4265
4242
|
}
|
|
4266
4243
|
/** Get the current textmode conversion pipeline. */
|
|
4267
4244
|
get pipeline() {
|
|
4268
|
-
if (this._isDestroyed)
|
|
4269
|
-
throw new Error("Cannot access pipeline: Textmodifier instance has been destroyed");
|
|
4270
4245
|
return this._pipeline;
|
|
4271
4246
|
}
|
|
4272
4247
|
/** Get the current frame count. */
|
|
4273
4248
|
get frameCount() {
|
|
4274
|
-
return this.
|
|
4249
|
+
return this._frameCount;
|
|
4250
|
+
}
|
|
4251
|
+
set frameCount(e) {
|
|
4252
|
+
this._frameCount = e;
|
|
4275
4253
|
}
|
|
4276
4254
|
/** Get the width of the canvas. */
|
|
4277
4255
|
get width() {
|
|
4278
|
-
return this.
|
|
4256
|
+
return this.textmodeCanvas.width;
|
|
4279
4257
|
}
|
|
4280
4258
|
/** Get the height of the canvas. */
|
|
4281
4259
|
get height() {
|
|
4282
|
-
return this.
|
|
4260
|
+
return this.textmodeCanvas.height;
|
|
4283
4261
|
}
|
|
4284
|
-
/** Check if
|
|
4285
|
-
get
|
|
4286
|
-
return this.
|
|
4262
|
+
/** Check if the instance has been disposed/destroyed. */
|
|
4263
|
+
get isDisposed() {
|
|
4264
|
+
return this._isDisposed;
|
|
4287
4265
|
}
|
|
4288
4266
|
}
|
|
4289
4267
|
class O {
|
|
@@ -4376,26 +4354,26 @@ class O {
|
|
|
4376
4354
|
* ```
|
|
4377
4355
|
*/
|
|
4378
4356
|
static get version() {
|
|
4379
|
-
return "0.1.4-beta.
|
|
4357
|
+
return "0.1.4-beta.5";
|
|
4380
4358
|
}
|
|
4381
4359
|
constructor() {
|
|
4382
4360
|
throw new Error("Textmode is a static class and cannot be instantiated.");
|
|
4383
4361
|
}
|
|
4384
4362
|
}
|
|
4385
|
-
const
|
|
4363
|
+
const Xe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4386
4364
|
__proto__: null
|
|
4387
4365
|
}, Symbol.toStringTag, { value: "Module" })), Ne = O.create, Oe = O.setErrorLevel, We = O.version;
|
|
4388
4366
|
export {
|
|
4389
4367
|
be as TextmodeCanvas,
|
|
4390
4368
|
Ue as TextmodeConversionPipeline,
|
|
4391
|
-
|
|
4369
|
+
oe as TextmodeErrorLevel,
|
|
4392
4370
|
xe as TextmodeFont,
|
|
4393
4371
|
ve as TextmodeGrid,
|
|
4394
4372
|
I as Textmodifier,
|
|
4395
|
-
|
|
4373
|
+
He as converters,
|
|
4396
4374
|
Ne as create,
|
|
4397
4375
|
O as default,
|
|
4398
|
-
|
|
4376
|
+
Xe as export,
|
|
4399
4377
|
Oe as setErrorLevel,
|
|
4400
4378
|
O as textmode,
|
|
4401
4379
|
We as version
|