textmode.js 0.1.4-beta.2 → 0.1.4-beta.3
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 +322 -219
- package/dist/textmode.esm.min.js +402 -299
- package/dist/textmode.umd.js +3 -3
- package/dist/textmode.umd.min.js +12 -12
- package/dist/types/textmode/Textmodifier.d.ts +85 -0
- package/package.json +2 -2
package/dist/textmode.esm.min.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
var se = Object.defineProperty;
|
|
2
|
-
var
|
|
3
|
-
var
|
|
2
|
+
var oe = (h, e, t) => e in h ? se(h, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[e] = t;
|
|
3
|
+
var a = (h, e, t) => oe(h, 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
|
+
a(this, "originalError");
|
|
9
|
+
a(this, "context");
|
|
10
10
|
this.name = "TextmodeError", this.originalError = r, this.context = i;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
@@ -18,8 +18,8 @@ class F extends Error {
|
|
|
18
18
|
i += `
|
|
19
19
|
|
|
20
20
|
📋 Context:`;
|
|
21
|
-
for (const [s,
|
|
22
|
-
const n = F.formatValue(
|
|
21
|
+
for (const [s, o] of Object.entries(r)) {
|
|
22
|
+
const n = F.formatValue(o);
|
|
23
23
|
i += `
|
|
24
24
|
- ${s}: ${n}`;
|
|
25
25
|
}
|
|
@@ -41,7 +41,7 @@ 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((o) => `${o}: ${F.formatValue(t[o])}`).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
|
}
|
|
@@ -49,7 +49,7 @@ class F extends Error {
|
|
|
49
49
|
var ne = /* @__PURE__ */ ((h) => (h[h.SILENT = 0] = "SILENT", h[h.WARNING = 1] = "WARNING", h[h.ERROR = 2] = "ERROR", h[h.THROW = 3] = "THROW", h))(ne || {});
|
|
50
50
|
const E = class E {
|
|
51
51
|
constructor() {
|
|
52
|
-
|
|
52
|
+
a(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
|
+
a(E, "_instance", null);
|
|
107
107
|
let $ = E;
|
|
108
108
|
const x = $.getInstance();
|
|
109
|
-
class
|
|
109
|
+
class ae {
|
|
110
110
|
constructor(e, t, r = t, i = {}) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
a(this, "gl");
|
|
112
|
+
a(this, "_framebuffer");
|
|
113
|
+
a(this, "_texture");
|
|
114
|
+
a(this, "_width");
|
|
115
|
+
a(this, "_height");
|
|
116
|
+
a(this, "options");
|
|
117
|
+
a(this, "previousState", null);
|
|
118
|
+
a(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 oe {
|
|
|
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 o = new Uint8Array(this._width * this._height * 4), n = s.getParameter(s.FRAMEBUFFER_BINDING);
|
|
193
|
+
return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(0, 0, this._width, this._height, s.RGBA, s.UNSIGNED_BYTE, o), s.bindFramebuffer(s.FRAMEBUFFER, n), o;
|
|
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 o = new Uint8Array(4), n = s.getParameter(s.FRAMEBUFFER_BINDING);
|
|
197
|
+
return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, 1, 1, s.RGBA, s.UNSIGNED_BYTE, o), s.bindFramebuffer(s.FRAMEBUFFER, n), [o[0], o[1], o[2], o[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 o = new Uint8Array(r * i * 4), n = s.getParameter(s.FRAMEBUFFER_BINDING);
|
|
201
|
+
return s.bindFramebuffer(s.FRAMEBUFFER, this._framebuffer), s.readPixels(e, t, r, i, s.RGBA, s.UNSIGNED_BYTE, o), s.bindFramebuffer(s.FRAMEBUFFER, n), o;
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
@@ -233,24 +233,24 @@ class oe {
|
|
|
233
233
|
}
|
|
234
234
|
class Q {
|
|
235
235
|
constructor(e, t, r) {
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
236
|
+
a(this, "gl");
|
|
237
|
+
a(this, "x");
|
|
238
|
+
a(this, "y");
|
|
239
239
|
this.gl = e, this.x = t, this.y = r;
|
|
240
240
|
}
|
|
241
241
|
}
|
|
242
242
|
class A {
|
|
243
243
|
constructor(e, t, r, i, s) {
|
|
244
244
|
/** The WebGL rendering context */
|
|
245
|
-
|
|
245
|
+
a(this, "gl");
|
|
246
246
|
/** The vertex buffer containing position and texture coordinates */
|
|
247
|
-
|
|
247
|
+
a(this, "vertexBuffer");
|
|
248
248
|
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
249
|
-
|
|
249
|
+
a(this, "vertexCount", 6);
|
|
250
250
|
/** Bytes per vertex: depends on position format (vec2 vs vec3) */
|
|
251
|
-
|
|
251
|
+
a(this, "bytesPerVertex");
|
|
252
252
|
this.gl = e, this.bytesPerVertex = 16;
|
|
253
|
-
const
|
|
253
|
+
const o = e.getParameter(e.VIEWPORT), n = o[2], l = o[3], c = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, u = t / n * 2 - 1, d = (t + i) / n * 2 - 1;
|
|
254
254
|
let f, g;
|
|
255
255
|
c ? (f = r / l * 2 - 1, g = (r + s) / l * 2 - 1) : (f = 1 - r / l * 2, g = 1 - (r + s) / l * 2);
|
|
256
256
|
let p, _, b, C;
|
|
@@ -307,11 +307,11 @@ class A {
|
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
309
|
class he extends Q {
|
|
310
|
-
constructor(t, r, i, s,
|
|
310
|
+
constructor(t, r, i, s, o) {
|
|
311
311
|
super(t, r, i);
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
this.width = s, this.height =
|
|
312
|
+
a(this, "width");
|
|
313
|
+
a(this, "height");
|
|
314
|
+
this.width = s, this.height = o;
|
|
315
315
|
}
|
|
316
316
|
/**
|
|
317
317
|
* Render the filled rectangle using the existing Rectangle geometry.
|
|
@@ -326,20 +326,20 @@ class he extends Q {
|
|
|
326
326
|
*/
|
|
327
327
|
renderStroke(t) {
|
|
328
328
|
if (t <= 0) return;
|
|
329
|
-
const r = new A(this.gl, this.x, this.y, this.width, t), i = new A(this.gl, this.x + this.width - t, this.y, t, this.height), s = new A(this.gl, this.x, this.y + this.height - t, this.width, t),
|
|
330
|
-
r.render(), i.render(), s.render(),
|
|
329
|
+
const r = new A(this.gl, this.x, this.y, this.width, t), i = new A(this.gl, this.x + this.width - t, this.y, t, this.height), s = new A(this.gl, this.x, this.y + this.height - t, this.width, t), o = new A(this.gl, this.x, this.y, t, this.height);
|
|
330
|
+
r.render(), i.render(), s.render(), o.render();
|
|
331
331
|
}
|
|
332
332
|
}
|
|
333
333
|
class le {
|
|
334
|
-
constructor(e, t, r, i, s,
|
|
334
|
+
constructor(e, t, r, i, s, o) {
|
|
335
335
|
/** The WebGL rendering context */
|
|
336
|
-
|
|
336
|
+
a(this, "gl");
|
|
337
337
|
/** The vertex buffer containing position and texture coordinates */
|
|
338
|
-
|
|
338
|
+
a(this, "vertexBuffer");
|
|
339
339
|
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
340
|
-
|
|
340
|
+
a(this, "vertexCount", 6);
|
|
341
341
|
/** Bytes per vertex: vec2+vec2 = 16 bytes */
|
|
342
|
-
|
|
342
|
+
a(this, "bytesPerVertex");
|
|
343
343
|
this.gl = e, this.bytesPerVertex = 16;
|
|
344
344
|
const n = e.getParameter(e.VIEWPORT), l = n[2], c = n[3], u = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, d = i - t, f = s - r, g = Math.sqrt(d * d + f * f);
|
|
345
345
|
if (g === 0) {
|
|
@@ -347,7 +347,7 @@ class le {
|
|
|
347
347
|
this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, ie, e.STATIC_DRAW);
|
|
348
348
|
return;
|
|
349
349
|
}
|
|
350
|
-
const p = d / g, b = -(f / g), C = p, v =
|
|
350
|
+
const p = d / g, b = -(f / g), C = p, v = o / 2, w = t + b * v, D = r + C * v, R = t - b * v, y = r - C * v, P = i + b * v, M = s + C * v, Z = i - b * v, W = s - C * v, J = w / l * 2 - 1, K = R / l * 2 - 1, ee = P / l * 2 - 1, te = Z / l * 2 - 1;
|
|
351
351
|
let B, G, V, k;
|
|
352
352
|
u ? (B = D / c * 2 - 1, G = y / c * 2 - 1, V = M / c * 2 - 1, k = W / c * 2 - 1) : (B = 1 - D / c * 2, G = 1 - y / c * 2, V = 1 - M / c * 2, k = 1 - W / c * 2);
|
|
353
353
|
const re = this.generateLineVertices(
|
|
@@ -405,7 +405,7 @@ class le {
|
|
|
405
405
|
* Uses the four corners calculated based on line direction and thickness
|
|
406
406
|
* @private
|
|
407
407
|
*/
|
|
408
|
-
generateLineVertices(e, t, r, i, s,
|
|
408
|
+
generateLineVertices(e, t, r, i, s, o, n, l) {
|
|
409
409
|
return new Float32Array([
|
|
410
410
|
e,
|
|
411
411
|
t,
|
|
@@ -418,7 +418,7 @@ class le {
|
|
|
418
418
|
1,
|
|
419
419
|
// corner2 (start - perpendicular)
|
|
420
420
|
s,
|
|
421
|
-
|
|
421
|
+
o,
|
|
422
422
|
1,
|
|
423
423
|
0,
|
|
424
424
|
// corner3 (end + perpendicular)
|
|
@@ -433,7 +433,7 @@ class le {
|
|
|
433
433
|
1,
|
|
434
434
|
// corner4 (end - perpendicular)
|
|
435
435
|
s,
|
|
436
|
-
|
|
436
|
+
o,
|
|
437
437
|
1,
|
|
438
438
|
0
|
|
439
439
|
// corner3 (end + perpendicular)
|
|
@@ -450,11 +450,11 @@ class le {
|
|
|
450
450
|
}
|
|
451
451
|
}
|
|
452
452
|
class ce extends Q {
|
|
453
|
-
constructor(t, r, i, s,
|
|
453
|
+
constructor(t, r, i, s, o) {
|
|
454
454
|
super(t, r, i);
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
this.x2 = s, this.y2 =
|
|
455
|
+
a(this, "x2");
|
|
456
|
+
a(this, "y2");
|
|
457
|
+
this.x2 = s, this.y2 = o;
|
|
458
458
|
}
|
|
459
459
|
/**
|
|
460
460
|
* Lines don't support fill rendering - this method does nothing.
|
|
@@ -473,18 +473,18 @@ class ce extends Q {
|
|
|
473
473
|
}
|
|
474
474
|
class T {
|
|
475
475
|
constructor(e, t, r) {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
476
|
+
a(this, "gl");
|
|
477
|
+
a(this, "program");
|
|
478
|
+
a(this, "uniformLocations", /* @__PURE__ */ new Map());
|
|
479
|
+
a(this, "attributeLocations", /* @__PURE__ */ new Map());
|
|
480
|
+
a(this, "textureUnitCounter", 0);
|
|
481
481
|
this.gl = e, this.program = this.createProgram(t, r), this.cacheLocations();
|
|
482
482
|
}
|
|
483
483
|
createProgram(e, t) {
|
|
484
484
|
const r = this.createShader(this.gl.VERTEX_SHADER, e), i = this.createShader(this.gl.FRAGMENT_SHADER, t), s = this.gl.createProgram();
|
|
485
485
|
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: ${
|
|
486
|
+
const o = this.gl.getProgramInfoLog(s);
|
|
487
|
+
throw new Error(`Shader program link error: ${o}`);
|
|
488
488
|
}
|
|
489
489
|
return this.gl.deleteShader(r), this.gl.deleteShader(i), s;
|
|
490
490
|
}
|
|
@@ -534,7 +534,7 @@ class T {
|
|
|
534
534
|
this.gl.uniform1i(r, t ? 1 : 0);
|
|
535
535
|
else if (Array.isArray(t))
|
|
536
536
|
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((
|
|
537
|
+
const s = t.map((o) => Math.floor(o));
|
|
538
538
|
switch (s.length) {
|
|
539
539
|
case 2:
|
|
540
540
|
this.gl.uniform2iv(r, s);
|
|
@@ -627,22 +627,22 @@ class T {
|
|
|
627
627
|
var S = "attribute vec2 a_position;attribute vec2 a_texCoord;varying vec2 v_uv;uniform float u_rotation;uniform vec2 u_center;uniform float u_aspectRatio;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){v_uv=a_texCoord;vec2 pos=a_position;pos-=u_center;pos.x*=u_aspectRatio;pos=rotate2D(-u_rotation)*pos;pos.x/=u_aspectRatio;pos+=u_center;gl_Position=vec4(pos,0.0,1.0);}", ue = "precision lowp float;uniform sampler2D u_texture;varying vec2 v_uv;void main(){gl_FragColor=texture2D(u_texture,v_uv);}", de = "precision lowp float;uniform vec4 u_color;void main(){gl_FragColor=u_color;}";
|
|
628
628
|
class fe {
|
|
629
629
|
constructor(e) {
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
630
|
+
a(this, "gl");
|
|
631
|
+
a(this, "imageShader");
|
|
632
|
+
a(this, "solidColorShader");
|
|
633
|
+
a(this, "currentShader", null);
|
|
634
634
|
// Fill state management - default: white fill enabled
|
|
635
|
-
|
|
636
|
-
|
|
635
|
+
a(this, "currentFillColor", [1, 1, 1, 1]);
|
|
636
|
+
a(this, "fillMode", !0);
|
|
637
637
|
// Stroke state management - default: black stroke enabled, weight 1
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
638
|
+
a(this, "currentStrokeColor", [0, 0, 0, 1]);
|
|
639
|
+
a(this, "currentStrokeWeight", 1);
|
|
640
|
+
a(this, "strokeMode", !0);
|
|
641
641
|
// Transformation state management
|
|
642
|
-
|
|
642
|
+
a(this, "currentRotation", 0);
|
|
643
643
|
// in degrees
|
|
644
644
|
// State stack for push/pop functionality
|
|
645
|
-
|
|
645
|
+
a(this, "stateStack", []);
|
|
646
646
|
this.gl = e, this.imageShader = new T(this.gl, S, ue), this.solidColorShader = new T(this.gl, S, de), this.gl.enable(this.gl.BLEND), this.gl.blendEquation(this.gl.FUNC_ADD), this.gl.blendFunc(this.gl.ONE, this.gl.ONE_MINUS_SRC_ALPHA);
|
|
647
647
|
}
|
|
648
648
|
/**
|
|
@@ -766,8 +766,8 @@ class fe {
|
|
|
766
766
|
s.renderFill(), this.currentShader = null;
|
|
767
767
|
return;
|
|
768
768
|
}
|
|
769
|
-
const
|
|
770
|
-
this.fillMode && (this.shader(
|
|
769
|
+
const o = this.solidColorShader, { centerX: n, centerY: l, radians: c, aspectRatio: u } = this.calculateRotationParams(e, t, r, i);
|
|
770
|
+
this.fillMode && (this.shader(o), this.setUniform("u_color", this.currentFillColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [n, l]), this.setUniform("u_aspectRatio", u), s.renderFill()), this.strokeMode && (this.shader(o), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [n, l]), this.setUniform("u_aspectRatio", u), s.renderStroke(this.currentStrokeWeight)), this.currentShader = null;
|
|
771
771
|
}
|
|
772
772
|
/**
|
|
773
773
|
* Draw a line from (x1, y1) to (x2, y2) with the current stroke settings.
|
|
@@ -789,14 +789,14 @@ class fe {
|
|
|
789
789
|
s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
|
|
790
790
|
return;
|
|
791
791
|
}
|
|
792
|
-
const
|
|
793
|
-
this.shader(
|
|
792
|
+
const o = this.solidColorShader, n = (e + r) / 2, l = (t + i) / 2, c = Math.abs(r - e), u = Math.abs(i - t), { centerX: d, centerY: f, radians: g, aspectRatio: p } = this.calculateRotationParams(n - c / 2, l - u / 2, c, u);
|
|
793
|
+
this.shader(o), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", g), this.setUniform("u_center", [d, f]), this.setUniform("u_aspectRatio", p), s.renderStroke(this.currentStrokeWeight), this.currentShader = null;
|
|
794
794
|
}
|
|
795
795
|
/**
|
|
796
796
|
* Calculate rotation parameters for built-in shaders (NDC coordinates)
|
|
797
797
|
*/
|
|
798
798
|
calculateRotationParams(e, t, r, i) {
|
|
799
|
-
const s = this.gl.getParameter(this.gl.VIEWPORT),
|
|
799
|
+
const s = this.gl.getParameter(this.gl.VIEWPORT), o = s[2], n = s[3], l = o / n, c = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING) !== null, u = e + r / 2, d = t + i / 2, f = u / o * 2 - 1;
|
|
800
800
|
let g;
|
|
801
801
|
c ? g = d / n * 2 - 1 : g = 1 - d / n * 2;
|
|
802
802
|
const p = this.currentRotation * Math.PI / 180;
|
|
@@ -806,7 +806,7 @@ class fe {
|
|
|
806
806
|
* Create a new framebuffer
|
|
807
807
|
*/
|
|
808
808
|
createFramebuffer(e, t, r = {}) {
|
|
809
|
-
return new
|
|
809
|
+
return new ae(this.gl, e, t, r);
|
|
810
810
|
}
|
|
811
811
|
/**
|
|
812
812
|
* Fill the current framebuffer with a solid color
|
|
@@ -850,18 +850,18 @@ class fe {
|
|
|
850
850
|
*/
|
|
851
851
|
image(e, t, r, i, s) {
|
|
852
852
|
this.shader(this.imageShader), this.setUniform("u_texture", e.texture);
|
|
853
|
-
const { centerX:
|
|
853
|
+
const { centerX: o, centerY: n, radians: l, aspectRatio: c } = this.calculateRotationParams(
|
|
854
854
|
t,
|
|
855
855
|
r,
|
|
856
856
|
i ?? e.width,
|
|
857
857
|
s ?? e.height
|
|
858
858
|
);
|
|
859
|
-
this.setUniform("u_rotation", l), this.setUniform("u_center", [
|
|
859
|
+
this.setUniform("u_rotation", l), this.setUniform("u_center", [o, n]), this.setUniform("u_aspectRatio", c), this.rect(t, r, i ?? e.width, s ?? e.height);
|
|
860
860
|
}
|
|
861
861
|
}
|
|
862
862
|
var m = {};
|
|
863
863
|
m.parse = function(h) {
|
|
864
|
-
var e = function(s,
|
|
864
|
+
var e = function(s, o, n, l) {
|
|
865
865
|
var c = m.T, u = {
|
|
866
866
|
cmap: c.cmap,
|
|
867
867
|
head: c.head,
|
|
@@ -870,7 +870,7 @@ m.parse = function(h) {
|
|
|
870
870
|
hmtx: c.hmtx,
|
|
871
871
|
loca: c.loca,
|
|
872
872
|
glyf: c.glyf
|
|
873
|
-
}, d = { _data: s, _index:
|
|
873
|
+
}, d = { _data: s, _index: o, _offset: n };
|
|
874
874
|
for (var f in u) {
|
|
875
875
|
var g = m.findTable(s, f, n);
|
|
876
876
|
if (g) {
|
|
@@ -883,7 +883,7 @@ m.parse = function(h) {
|
|
|
883
883
|
return [i];
|
|
884
884
|
};
|
|
885
885
|
m.findTable = function(h, e, t) {
|
|
886
|
-
for (var r = m.B, i = r.readUshort(h, t + 4), s = t + 12,
|
|
886
|
+
for (var r = m.B, i = r.readUshort(h, t + 4), s = t + 12, o = 0; o < i; o++) {
|
|
887
887
|
var n = r.readASCII(h, s, 4);
|
|
888
888
|
r.readUint(h, s + 4);
|
|
889
889
|
var l = r.readUint(h, s + 8), c = r.readUint(h, s + 12);
|
|
@@ -929,7 +929,7 @@ m.T.cmap = {
|
|
|
929
929
|
parseTab: function(h, e, t) {
|
|
930
930
|
var r = { tables: [], ids: {}, off: e };
|
|
931
931
|
h = new Uint8Array(h.buffer, e, t), e = 0;
|
|
932
|
-
var i = m.B, s = i.readUshort,
|
|
932
|
+
var i = m.B, s = i.readUshort, o = m.T.cmap;
|
|
933
933
|
s(h, e), e += 2;
|
|
934
934
|
var n = s(h, e);
|
|
935
935
|
e += 2;
|
|
@@ -946,14 +946,14 @@ m.T.cmap = {
|
|
|
946
946
|
var _ = {};
|
|
947
947
|
l.push(f);
|
|
948
948
|
var b = _.format = s(h, f);
|
|
949
|
-
b == 4 ? _ =
|
|
949
|
+
b == 4 ? _ = o.parse4(h, f, _) : b == 12 && (_ = o.parse12(h, f, _)), r.tables.push(_);
|
|
950
950
|
}
|
|
951
951
|
r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] = p;
|
|
952
952
|
}
|
|
953
953
|
return r;
|
|
954
954
|
},
|
|
955
955
|
parse4: function(h, e, t) {
|
|
956
|
-
var r = m.B, i = r.readUshort, s = r.readUshorts,
|
|
956
|
+
var r = m.B, i = r.readUshort, s = r.readUshorts, o = e;
|
|
957
957
|
e += 2;
|
|
958
958
|
var n = i(h, e);
|
|
959
959
|
e += 2, i(h, e), e += 2;
|
|
@@ -963,15 +963,15 @@ m.T.cmap = {
|
|
|
963
963
|
t.searchRange = i(h, e), e += 2, t.entrySelector = i(h, e), e += 2, t.rangeShift = i(h, e), e += 2, t.endCount = s(h, e, c), e += c * 2, e += 2, t.startCount = s(h, e, c), e += c * 2, t.idDelta = [];
|
|
964
964
|
for (var u = 0; u < c; u++)
|
|
965
965
|
t.idDelta.push(r.readShort(h, e)), e += 2;
|
|
966
|
-
return t.idRangeOffset = s(h, e, c), e += c * 2, t.glyphIdArray = s(h, e,
|
|
966
|
+
return t.idRangeOffset = s(h, e, c), e += c * 2, t.glyphIdArray = s(h, e, o + n - e >> 1), t;
|
|
967
967
|
},
|
|
968
968
|
parse12: function(h, e, t) {
|
|
969
969
|
var r = m.B, i = r.readUint;
|
|
970
970
|
e += 4, i(h, e), e += 4, i(h, e), e += 4;
|
|
971
971
|
var s = i(h, e) * 3;
|
|
972
972
|
e += 4;
|
|
973
|
-
for (var
|
|
974
|
-
|
|
973
|
+
for (var o = t.groups = new Uint32Array(s), n = 0; n < s; n += 3)
|
|
974
|
+
o[n] = i(h, e + (n << 2)), o[n + 1] = i(h, e + (n << 2) + 4), o[n + 2] = i(h, e + (n << 2) + 8);
|
|
975
975
|
return t;
|
|
976
976
|
}
|
|
977
977
|
};
|
|
@@ -1002,20 +1002,20 @@ m.T.hhea = {
|
|
|
1002
1002
|
"res3",
|
|
1003
1003
|
"metricDataFormat",
|
|
1004
1004
|
"numberOfHMetrics"
|
|
1005
|
-
],
|
|
1006
|
-
var n = s[
|
|
1007
|
-
i[n] = l(h, e +
|
|
1005
|
+
], o = 0; o < s.length; o++) {
|
|
1006
|
+
var n = s[o], l = n == "advanceWidthMax" || n == "numberOfHMetrics" ? r.readUshort : r.readShort;
|
|
1007
|
+
i[n] = l(h, e + o * 2);
|
|
1008
1008
|
}
|
|
1009
1009
|
return i;
|
|
1010
1010
|
}
|
|
1011
1011
|
};
|
|
1012
1012
|
m.T.hmtx = {
|
|
1013
1013
|
parseTab: function(h, e, t, r) {
|
|
1014
|
-
for (var i = m.B, s = [],
|
|
1015
|
-
c = i.readUshort(h, e + (d << 2)), u = i.readShort(h, e + (d << 2) + 2), s.push(c),
|
|
1014
|
+
for (var i = m.B, s = [], o = [], n = r.maxp.numGlyphs, l = r.hhea.numberOfHMetrics, c = 0, u = 0, d = 0; d < l; )
|
|
1015
|
+
c = i.readUshort(h, e + (d << 2)), u = i.readShort(h, e + (d << 2) + 2), s.push(c), o.push(u), d++;
|
|
1016
1016
|
for (; d < n; )
|
|
1017
|
-
s.push(c),
|
|
1018
|
-
return { aWidth: s, lsBearing:
|
|
1017
|
+
s.push(c), o.push(u), d++;
|
|
1018
|
+
return { aWidth: s, lsBearing: o };
|
|
1019
1019
|
}
|
|
1020
1020
|
};
|
|
1021
1021
|
m.T.maxp = {
|
|
@@ -1026,55 +1026,55 @@ m.T.maxp = {
|
|
|
1026
1026
|
};
|
|
1027
1027
|
m.T.loca = {
|
|
1028
1028
|
parseTab: function(h, e, t, r) {
|
|
1029
|
-
var i = m.B, s = [],
|
|
1030
|
-
if (
|
|
1031
|
-
if (
|
|
1029
|
+
var i = m.B, s = [], o = r.head.indexToLocFormat, n = r.maxp.numGlyphs + 1;
|
|
1030
|
+
if (o == 0) for (var l = 0; l < n; l++) s.push(i.readUshort(h, e + (l << 1)) << 1);
|
|
1031
|
+
if (o == 1) for (var l = 0; l < n; l++) s.push(i.readUint(h, e + (l << 2)));
|
|
1032
1032
|
return s;
|
|
1033
1033
|
}
|
|
1034
1034
|
};
|
|
1035
1035
|
m.T.glyf = {
|
|
1036
1036
|
parseTab: function(h, e, t, r) {
|
|
1037
|
-
for (var i = [], s = r.maxp.numGlyphs,
|
|
1037
|
+
for (var i = [], s = r.maxp.numGlyphs, o = 0; o < s; o++) i.push(null);
|
|
1038
1038
|
return i;
|
|
1039
1039
|
},
|
|
1040
1040
|
_parseGlyf: function(h, e) {
|
|
1041
1041
|
var t = m.B, r = h._data, i = h.loca;
|
|
1042
1042
|
if (i[e] == i[e + 1]) return null;
|
|
1043
|
-
var s = m.findTable(r, "glyf", h._offset)[0] + i[e],
|
|
1044
|
-
if (
|
|
1045
|
-
if (
|
|
1046
|
-
|
|
1047
|
-
for (var n = 0; n <
|
|
1048
|
-
|
|
1043
|
+
var s = m.findTable(r, "glyf", h._offset)[0] + i[e], o = {};
|
|
1044
|
+
if (o.noc = t.readShort(r, s), s += 2, o.xMin = t.readShort(r, s), s += 2, o.yMin = t.readShort(r, s), s += 2, o.xMax = t.readShort(r, s), s += 2, o.yMax = t.readShort(r, s), s += 2, o.xMin >= o.xMax || o.yMin >= o.yMax) return null;
|
|
1045
|
+
if (o.noc > 0) {
|
|
1046
|
+
o.endPts = [];
|
|
1047
|
+
for (var n = 0; n < o.noc; n++)
|
|
1048
|
+
o.endPts.push(t.readUshort(r, s)), s += 2;
|
|
1049
1049
|
var l = t.readUshort(r, s);
|
|
1050
1050
|
if (s += 2, r.length - s < l) return null;
|
|
1051
1051
|
s += l;
|
|
1052
|
-
var c =
|
|
1053
|
-
|
|
1052
|
+
var c = o.endPts[o.noc - 1] + 1;
|
|
1053
|
+
o.flags = [];
|
|
1054
1054
|
for (var n = 0; n < c; n++) {
|
|
1055
1055
|
var u = r[s];
|
|
1056
|
-
if (s++,
|
|
1056
|
+
if (s++, o.flags.push(u), u & 8) {
|
|
1057
1057
|
var d = r[s];
|
|
1058
1058
|
s++;
|
|
1059
1059
|
for (var f = 0; f < d; f++)
|
|
1060
|
-
|
|
1060
|
+
o.flags.push(u), n++;
|
|
1061
1061
|
}
|
|
1062
1062
|
}
|
|
1063
|
-
|
|
1063
|
+
o.xs = [];
|
|
1064
1064
|
for (var n = 0; n < c; n++) {
|
|
1065
|
-
var g = (
|
|
1066
|
-
g ? (
|
|
1065
|
+
var g = (o.flags[n] & 2) != 0, p = (o.flags[n] & 16) != 0;
|
|
1066
|
+
g ? (o.xs.push(p ? r[s] : -r[s]), s++) : p ? o.xs.push(0) : (o.xs.push(t.readShort(r, s)), s += 2);
|
|
1067
1067
|
}
|
|
1068
|
-
|
|
1068
|
+
o.ys = [];
|
|
1069
1069
|
for (var n = 0; n < c; n++) {
|
|
1070
|
-
var g = (
|
|
1071
|
-
g ? (
|
|
1070
|
+
var g = (o.flags[n] & 4) != 0, p = (o.flags[n] & 32) != 0;
|
|
1071
|
+
g ? (o.ys.push(p ? r[s] : -r[s]), s++) : p ? o.ys.push(0) : (o.ys.push(t.readShort(r, s)), s += 2);
|
|
1072
1072
|
}
|
|
1073
1073
|
for (var _ = 0, b = 0, n = 0; n < c; n++)
|
|
1074
|
-
_ +=
|
|
1074
|
+
_ += o.xs[n], b += o.ys[n], o.xs[n] = _, o.ys[n] = b;
|
|
1075
1075
|
} else
|
|
1076
|
-
|
|
1077
|
-
return
|
|
1076
|
+
o.parts = [];
|
|
1077
|
+
return o;
|
|
1078
1078
|
}
|
|
1079
1079
|
};
|
|
1080
1080
|
typeof module < "u" && module.exports ? module.exports = m : typeof window < "u" && (window.Typr = m);
|
|
@@ -1109,9 +1109,9 @@ class me {
|
|
|
1109
1109
|
for (let r = 0; r < e.startCount.length; r++) {
|
|
1110
1110
|
const i = e.startCount[r], s = e.endCount[r];
|
|
1111
1111
|
if (!(i === 65535 && s === 65535)) {
|
|
1112
|
-
for (let
|
|
1113
|
-
if (this._calculateGlyphIndexFormat4(e,
|
|
1114
|
-
const l = String.fromCodePoint(
|
|
1112
|
+
for (let o = i; o <= s; o++)
|
|
1113
|
+
if (this._calculateGlyphIndexFormat4(e, o, r) > 0) {
|
|
1114
|
+
const l = String.fromCodePoint(o);
|
|
1115
1115
|
t.push(l);
|
|
1116
1116
|
}
|
|
1117
1117
|
}
|
|
@@ -1128,9 +1128,9 @@ class me {
|
|
|
1128
1128
|
if (!e.groups)
|
|
1129
1129
|
return t;
|
|
1130
1130
|
for (let r = 0; r < e.groups.length; r += 3) {
|
|
1131
|
-
const i = e.groups[r], s = e.groups[r + 1],
|
|
1131
|
+
const i = e.groups[r], s = e.groups[r + 1], o = e.groups[r + 2];
|
|
1132
1132
|
for (let n = i; n <= s; n++)
|
|
1133
|
-
if (
|
|
1133
|
+
if (o + (n - i) > 0) {
|
|
1134
1134
|
const c = String.fromCodePoint(n);
|
|
1135
1135
|
t.push(c);
|
|
1136
1136
|
}
|
|
@@ -1181,9 +1181,9 @@ class ge {
|
|
|
1181
1181
|
* @param renderer The WebGL renderer instance
|
|
1182
1182
|
*/
|
|
1183
1183
|
constructor(e) {
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1184
|
+
a(this, "_textureCanvas");
|
|
1185
|
+
a(this, "_textureContext");
|
|
1186
|
+
a(this, "_renderer");
|
|
1187
1187
|
this._renderer = e, this._textureCanvas = document.createElement("canvas"), this._textureContext = this._textureCanvas.getContext("2d", { willReadFrequently: !0, alpha: !1 });
|
|
1188
1188
|
}
|
|
1189
1189
|
/**
|
|
@@ -1195,12 +1195,12 @@ class ge {
|
|
|
1195
1195
|
* @returns Object containing framebuffer, columns, and rows
|
|
1196
1196
|
*/
|
|
1197
1197
|
createTextureAtlas(e, t, r, i) {
|
|
1198
|
-
const s = e.length,
|
|
1199
|
-
this._setupCanvas(l, c, r, i), this._renderCharactersToCanvas(e, t,
|
|
1198
|
+
const s = e.length, o = Math.ceil(Math.sqrt(s)), n = Math.ceil(s / o), l = t.width * o, c = t.height * n;
|
|
1199
|
+
this._setupCanvas(l, c, r, i), this._renderCharactersToCanvas(e, t, o, r), this._applyBlackWhiteThreshold();
|
|
1200
1200
|
const u = this._renderer.createFramebuffer(l, c, { filter: "nearest" });
|
|
1201
1201
|
return u.update(this._textureCanvas), {
|
|
1202
1202
|
framebuffer: u,
|
|
1203
|
-
columns:
|
|
1203
|
+
columns: o,
|
|
1204
1204
|
rows: n
|
|
1205
1205
|
};
|
|
1206
1206
|
}
|
|
@@ -1225,7 +1225,7 @@ class ge {
|
|
|
1225
1225
|
*/
|
|
1226
1226
|
_renderCharactersToCanvas(e, t, r, i) {
|
|
1227
1227
|
for (let s = 0; s < e.length; s++) {
|
|
1228
|
-
const
|
|
1228
|
+
const o = s % r, n = Math.floor(s / r), l = o * t.width + t.width * 0.5, c = n * t.height + t.height * 0.5, u = Math.round(l - t.width * 0.5), d = Math.round(c - i * 0.5);
|
|
1229
1229
|
this._textureContext.fillText(e[s].character, u, d);
|
|
1230
1230
|
}
|
|
1231
1231
|
}
|
|
@@ -1238,7 +1238,7 @@ class ge {
|
|
|
1238
1238
|
_applyBlackWhiteThreshold(e = 128) {
|
|
1239
1239
|
const t = this._textureContext.getImageData(0, 0, this._textureCanvas.width, this._textureCanvas.height), r = t.data;
|
|
1240
1240
|
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],
|
|
1241
|
+
const s = 0.299 * r[i] + 0.587 * r[i + 1] + 0.114 * r[i + 2], o = e + 32, n = s > o ? 255 : 0;
|
|
1242
1242
|
r[i] = n, r[i + 1] = n, r[i + 2] = n;
|
|
1243
1243
|
}
|
|
1244
1244
|
this._textureContext.putImageData(t, 0, 0);
|
|
@@ -1249,8 +1249,8 @@ class _e {
|
|
|
1249
1249
|
* Creates a new MetricsCalculation instance.
|
|
1250
1250
|
*/
|
|
1251
1251
|
constructor() {
|
|
1252
|
-
|
|
1253
|
-
|
|
1252
|
+
a(this, "_tempCanvas");
|
|
1253
|
+
a(this, "_tempContext");
|
|
1254
1254
|
this._tempCanvas = document.createElement("canvas"), this._tempContext = this._tempCanvas.getContext("2d");
|
|
1255
1255
|
}
|
|
1256
1256
|
/**
|
|
@@ -1264,8 +1264,8 @@ class _e {
|
|
|
1264
1264
|
calculateMaxGlyphDimensions(e, t, r) {
|
|
1265
1265
|
this._tempContext.font = `${t}px ${r}`;
|
|
1266
1266
|
let i = 0, s = 0;
|
|
1267
|
-
for (const
|
|
1268
|
-
const n = this._tempContext.measureText(
|
|
1267
|
+
for (const o of e) {
|
|
1268
|
+
const n = this._tempContext.measureText(o), l = n.width, c = n.actualBoundingBoxAscent + n.actualBoundingBoxDescent;
|
|
1269
1269
|
l > 0 && (i = Math.max(i, l), s = Math.max(s, c));
|
|
1270
1270
|
}
|
|
1271
1271
|
return {
|
|
@@ -1283,7 +1283,7 @@ class pe {
|
|
|
1283
1283
|
*/
|
|
1284
1284
|
createCharacterObjects(e, t) {
|
|
1285
1285
|
return e.map((r, i) => {
|
|
1286
|
-
const s = r.codePointAt(0) || 0,
|
|
1286
|
+
const s = r.codePointAt(0) || 0, o = this._generateCharacterColor(i);
|
|
1287
1287
|
let n = 0;
|
|
1288
1288
|
if (t.hmtx && t.hmtx.aWidth) {
|
|
1289
1289
|
const l = this._getGlyphIndex(t, s);
|
|
@@ -1292,7 +1292,7 @@ class pe {
|
|
|
1292
1292
|
return {
|
|
1293
1293
|
character: r,
|
|
1294
1294
|
unicode: s,
|
|
1295
|
-
color:
|
|
1295
|
+
color: o,
|
|
1296
1296
|
advanceWidth: n
|
|
1297
1297
|
};
|
|
1298
1298
|
});
|
|
@@ -1314,9 +1314,9 @@ class pe {
|
|
|
1314
1314
|
if (i.idRangeOffset[s] === 0)
|
|
1315
1315
|
return t + i.idDelta[s] & 65535;
|
|
1316
1316
|
{
|
|
1317
|
-
const
|
|
1318
|
-
if (
|
|
1319
|
-
const n = i.glyphIdArray[
|
|
1317
|
+
const o = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
|
|
1318
|
+
if (o >= 0 && o < i.glyphIdArray.length) {
|
|
1319
|
+
const n = i.glyphIdArray[o];
|
|
1320
1320
|
if (n !== 0)
|
|
1321
1321
|
return n + i.idDelta[s] & 65535;
|
|
1322
1322
|
}
|
|
@@ -1372,20 +1372,20 @@ class xe {
|
|
|
1372
1372
|
* @ignore
|
|
1373
1373
|
*/
|
|
1374
1374
|
constructor(e, t = 16) {
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1375
|
+
a(this, "_font");
|
|
1376
|
+
a(this, "_characters", []);
|
|
1377
|
+
a(this, "_fontFramebuffer");
|
|
1378
|
+
a(this, "_fontSize", 16);
|
|
1379
|
+
a(this, "_textureColumns", 0);
|
|
1380
|
+
a(this, "_textureRows", 0);
|
|
1381
|
+
a(this, "_maxGlyphDimensions", { width: 0, height: 0 });
|
|
1382
|
+
a(this, "_fontFace");
|
|
1383
|
+
a(this, "_fontFamilyName", "UrsaFont");
|
|
1384
1384
|
// Component classes
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1385
|
+
a(this, "_characterExtractor");
|
|
1386
|
+
a(this, "_textureAtlas");
|
|
1387
|
+
a(this, "_metricsCalculator");
|
|
1388
|
+
a(this, "_characterColorMapper");
|
|
1389
1389
|
this._fontSize = t, this._characterExtractor = new me(), this._textureAtlas = new ge(e), this._metricsCalculator = new _e(), this._characterColorMapper = new pe();
|
|
1390
1390
|
}
|
|
1391
1391
|
/**
|
|
@@ -1556,25 +1556,25 @@ class ve {
|
|
|
1556
1556
|
*/
|
|
1557
1557
|
constructor(e, t, r) {
|
|
1558
1558
|
/** The number of columns in the grid. */
|
|
1559
|
-
|
|
1559
|
+
a(this, "_cols");
|
|
1560
1560
|
/** The number of rows in the grid. */
|
|
1561
|
-
|
|
1561
|
+
a(this, "_rows");
|
|
1562
1562
|
/** The total width of the grid in pixels. */
|
|
1563
|
-
|
|
1563
|
+
a(this, "_width");
|
|
1564
1564
|
/** The total height of the grid in pixels. */
|
|
1565
|
-
|
|
1565
|
+
a(this, "_height");
|
|
1566
1566
|
/** The offset to the outer canvas on the x-axis when centering the grid. */
|
|
1567
|
-
|
|
1567
|
+
a(this, "_offsetX");
|
|
1568
1568
|
/** The offset to the outer canvas on the y-axis when centering the grid. */
|
|
1569
|
-
|
|
1569
|
+
a(this, "_offsetY");
|
|
1570
1570
|
/** Whether the grid dimensions are fixed, or responsive based on the canvas dimensions. */
|
|
1571
|
-
|
|
1571
|
+
a(this, "_fixedDimensions", !1);
|
|
1572
1572
|
/** The canvas element used to determine the grid dimensions. */
|
|
1573
|
-
|
|
1573
|
+
a(this, "_canvas");
|
|
1574
1574
|
/** The width of each cell in the grid. */
|
|
1575
|
-
|
|
1575
|
+
a(this, "_cellWidth");
|
|
1576
1576
|
/** The height of each cell in the grid. */
|
|
1577
|
-
|
|
1577
|
+
a(this, "_cellHeight");
|
|
1578
1578
|
this._canvas = e, this._cellWidth = t, this._cellHeight = r, this.reset();
|
|
1579
1579
|
}
|
|
1580
1580
|
/**
|
|
@@ -1691,9 +1691,9 @@ class ve {
|
|
|
1691
1691
|
}
|
|
1692
1692
|
class be {
|
|
1693
1693
|
constructor(e, t = !1, r = {}) {
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1694
|
+
a(this, "_canvas");
|
|
1695
|
+
a(this, "captureSource");
|
|
1696
|
+
a(this, "_isStandalone");
|
|
1697
1697
|
this.captureSource = e, this._isStandalone = t, this._canvas = this.createCanvas(r.width, r.height);
|
|
1698
1698
|
}
|
|
1699
1699
|
createCanvas(e, t) {
|
|
@@ -1703,12 +1703,12 @@ class be {
|
|
|
1703
1703
|
r.width = e || 800, r.height = t || 600, document.body.appendChild(r);
|
|
1704
1704
|
else {
|
|
1705
1705
|
const s = this.captureSource.getBoundingClientRect();
|
|
1706
|
-
let
|
|
1706
|
+
let o = Math.round(s.width), n = Math.round(s.height);
|
|
1707
1707
|
if (this.captureSource instanceof HTMLVideoElement) {
|
|
1708
1708
|
const u = this.captureSource;
|
|
1709
|
-
(
|
|
1709
|
+
(o === 0 || n === 0) && u.videoWidth > 0 && u.videoHeight > 0 && (o = u.videoWidth, n = u.videoHeight);
|
|
1710
1710
|
}
|
|
1711
|
-
r.width =
|
|
1711
|
+
r.width = o, r.height = n, r.style.position = "absolute", r.style.pointerEvents = "none";
|
|
1712
1712
|
const l = window.getComputedStyle(this.captureSource);
|
|
1713
1713
|
let c = parseInt(l.zIndex || "0", 10);
|
|
1714
1714
|
isNaN(c) && (c = 0), r.style.zIndex = (c + 1).toString(), this.positionOverlayCanvas(r), (i = this.captureSource.parentNode) == null || i.insertBefore(r, this.captureSource.nextSibling);
|
|
@@ -1731,8 +1731,8 @@ class be {
|
|
|
1731
1731
|
const r = this.captureSource.getBoundingClientRect();
|
|
1732
1732
|
let i = Math.round(r.width), s = Math.round(r.height);
|
|
1733
1733
|
if (this.captureSource instanceof HTMLVideoElement) {
|
|
1734
|
-
const
|
|
1735
|
-
(i === 0 || s === 0) &&
|
|
1734
|
+
const o = this.captureSource;
|
|
1735
|
+
(i === 0 || s === 0) && o.videoWidth > 0 && o.videoHeight > 0 && (i = o.videoWidth, s = o.videoHeight);
|
|
1736
1736
|
}
|
|
1737
1737
|
this._canvas.width = i, this._canvas.height = s, this.positionOverlayCanvas(this._canvas);
|
|
1738
1738
|
}
|
|
@@ -1795,15 +1795,15 @@ class U {
|
|
|
1795
1795
|
* @ignore
|
|
1796
1796
|
*/
|
|
1797
1797
|
constructor(e, t, r, i = {}) {
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1798
|
+
a(this, "renderer");
|
|
1799
|
+
a(this, "fontManager");
|
|
1800
|
+
a(this, "grid");
|
|
1801
|
+
a(this, "_characterFramebuffer");
|
|
1802
|
+
a(this, "_primaryColorFramebuffer");
|
|
1803
|
+
a(this, "_secondaryColorFramebuffer");
|
|
1804
|
+
a(this, "_rotationFramebuffer");
|
|
1805
|
+
a(this, "_transformFramebuffer");
|
|
1806
|
+
a(this, "_options");
|
|
1807
1807
|
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
1808
|
}
|
|
1809
1809
|
/**
|
|
@@ -1878,9 +1878,9 @@ class Ce {
|
|
|
1878
1878
|
*/
|
|
1879
1879
|
constructor(e, t) {
|
|
1880
1880
|
/** The framebuffer used to store the color palette. */
|
|
1881
|
-
|
|
1882
|
-
|
|
1883
|
-
|
|
1881
|
+
a(this, "_framebuffer");
|
|
1882
|
+
a(this, "_renderer");
|
|
1883
|
+
a(this, "_colors");
|
|
1884
1884
|
this._renderer = e, this._colors = t;
|
|
1885
1885
|
const r = Math.max(this._colors.length, 1);
|
|
1886
1886
|
this._framebuffer = this._renderer.createFramebuffer(r, 1), this._updateFramebuffer();
|
|
@@ -1894,8 +1894,8 @@ class Ce {
|
|
|
1894
1894
|
this._framebuffer.width !== e && this._framebuffer.resize(e, t);
|
|
1895
1895
|
const r = new Uint8Array(e * t * 4);
|
|
1896
1896
|
for (let i = 0; i < e; i++) {
|
|
1897
|
-
const s = i < this._colors.length ? this._colors[i] : [0, 0, 0],
|
|
1898
|
-
r[
|
|
1897
|
+
const s = i < this._colors.length ? this._colors[i] : [0, 0, 0], o = i * 4;
|
|
1898
|
+
r[o] = s[0], r[o + 1] = s[1], r[o + 2] = s[2], r[o + 3] = 255;
|
|
1899
1899
|
}
|
|
1900
1900
|
this._framebuffer.updatePixels(r, e, t);
|
|
1901
1901
|
}
|
|
@@ -1928,7 +1928,7 @@ class Ce {
|
|
|
1928
1928
|
class X extends U {
|
|
1929
1929
|
constructor(t, r, i, s = {}) {
|
|
1930
1930
|
super(t, r, i, s);
|
|
1931
|
-
|
|
1931
|
+
a(this, "palette");
|
|
1932
1932
|
this.palette = new Ce(this.renderer, this.fontManager.getCharacterColors(" .:-=+*%@#"));
|
|
1933
1933
|
}
|
|
1934
1934
|
/**
|
|
@@ -1952,7 +1952,7 @@ class X extends U {
|
|
|
1952
1952
|
*/
|
|
1953
1953
|
characterColor(t, r = t, i = t, s = 255) {
|
|
1954
1954
|
x.validate(
|
|
1955
|
-
[t, r, i, s].every((
|
|
1955
|
+
[t, r, i, s].every((o) => o >= 0 && o <= 255),
|
|
1956
1956
|
"Character color values must be between 0 and 255",
|
|
1957
1957
|
{ method: "characterColor", providedValues: { r: t, g: r, b: i, a: s } }
|
|
1958
1958
|
) && (this._options.characterColor = [t, r, i, s]);
|
|
@@ -1980,7 +1980,7 @@ class X extends U {
|
|
|
1980
1980
|
*/
|
|
1981
1981
|
cellColor(t, r = t, i = t, s = 255) {
|
|
1982
1982
|
x.validate(
|
|
1983
|
-
[t, r, i, s].every((
|
|
1983
|
+
[t, r, i, s].every((o) => o >= 0 && o <= 255),
|
|
1984
1984
|
"Cell color values must be between 0 and 255",
|
|
1985
1985
|
{ method: "cellColor", providedValues: { r: t, g: r, b: i, a: s } }
|
|
1986
1986
|
) && (this._options.cellColor = [t, r, i, s]);
|
|
@@ -2082,12 +2082,12 @@ class L extends X {
|
|
|
2082
2082
|
*/
|
|
2083
2083
|
constructor(t, r, i) {
|
|
2084
2084
|
super(t, r, i, { ...Re });
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2085
|
+
a(this, "sampleShader");
|
|
2086
|
+
a(this, "colorFillShader");
|
|
2087
|
+
a(this, "charMappingShader");
|
|
2088
|
+
a(this, "transformFillShader");
|
|
2089
|
+
a(this, "rotationFillShader");
|
|
2090
|
+
a(this, "sampleFramebuffer");
|
|
2091
2091
|
this.sampleShader = new T(t.context, S, Fe), this.colorFillShader = new T(t.context, S, we), this.transformFillShader = new T(t.context, S, ye), this.rotationFillShader = new T(t.context, S, Te), this.charMappingShader = new T(t.context, S, Se), this.sampleFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
|
|
2092
2092
|
}
|
|
2093
2093
|
convert(t) {
|
|
@@ -2127,17 +2127,17 @@ class Ue {
|
|
|
2127
2127
|
* @ignore
|
|
2128
2128
|
*/
|
|
2129
2129
|
constructor(e, t, r) {
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2130
|
+
a(this, "renderer");
|
|
2131
|
+
a(this, "font");
|
|
2132
|
+
a(this, "grid");
|
|
2133
|
+
a(this, "converters");
|
|
2134
|
+
a(this, "_resultFramebuffer");
|
|
2135
|
+
a(this, "_asciiShader");
|
|
2136
|
+
a(this, "_characterFramebuffer");
|
|
2137
|
+
a(this, "_primaryColorFramebuffer");
|
|
2138
|
+
a(this, "_secondaryColorFramebuffer");
|
|
2139
|
+
a(this, "_rotationFramebuffer");
|
|
2140
|
+
a(this, "_transformFramebuffer");
|
|
2141
2141
|
this.renderer = e, this.font = t, this.grid = r, this._asciiShader = this.renderer.createShader(S, Ee), this.converters = [
|
|
2142
2142
|
{ name: "brightness", converter: new L(e, t, r) },
|
|
2143
2143
|
{ name: "custom", converter: new U(e, t, r) }
|
|
@@ -2156,8 +2156,8 @@ class Ue {
|
|
|
2156
2156
|
const t = (r, i) => {
|
|
2157
2157
|
r.begin(), this.renderer.clear();
|
|
2158
2158
|
for (const s of this.converters) {
|
|
2159
|
-
const
|
|
2160
|
-
|
|
2159
|
+
const o = s.converter;
|
|
2160
|
+
o.options.enabled && this.renderer.image(i(o), 0, 0);
|
|
2161
2161
|
}
|
|
2162
2162
|
r.end();
|
|
2163
2163
|
};
|
|
@@ -2310,12 +2310,12 @@ class H {
|
|
|
2310
2310
|
* @returns Object containing all pixel data arrays
|
|
2311
2311
|
*/
|
|
2312
2312
|
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(),
|
|
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, o = t == null ? void 0 : t.transformFramebuffer, n = t == null ? void 0 : t.rotationFramebuffer;
|
|
2314
|
+
return r == null || r.loadPixels(), i == null || i.loadPixels(), s == null || s.loadPixels(), o == null || o.loadPixels(), n == null || n.loadPixels(), {
|
|
2315
2315
|
characterPixels: (r == null ? void 0 : r.pixels) || new Uint8Array(0),
|
|
2316
2316
|
primaryColorPixels: (i == null ? void 0 : i.pixels) || new Uint8Array(0),
|
|
2317
2317
|
secondaryColorPixels: (s == null ? void 0 : s.pixels) || new Uint8Array(0),
|
|
2318
|
-
transformPixels: (
|
|
2318
|
+
transformPixels: (o == null ? void 0 : o.pixels) || new Uint8Array(0),
|
|
2319
2319
|
rotationPixels: (n == null ? void 0 : n.pixels) || new Uint8Array(0)
|
|
2320
2320
|
};
|
|
2321
2321
|
}
|
|
@@ -2363,8 +2363,8 @@ class N {
|
|
|
2363
2363
|
*/
|
|
2364
2364
|
downloadFile(e, t, r) {
|
|
2365
2365
|
try {
|
|
2366
|
-
const i = this.createBlob(e, r), s = URL.createObjectURL(i),
|
|
2367
|
-
|
|
2366
|
+
const i = this.createBlob(e, r), s = URL.createObjectURL(i), o = document.createElement("a");
|
|
2367
|
+
o.href = s, o.download = t, o.style.display = "none", o.rel = "noopener", document.body.appendChild(o), o.click(), document.body.removeChild(o), URL.revokeObjectURL(s);
|
|
2368
2368
|
} catch (i) {
|
|
2369
2369
|
throw console.error("Failed to download file:", i), new Error(`File download failed: ${i instanceof Error ? i.message : "Unknown error"}`);
|
|
2370
2370
|
}
|
|
@@ -2411,7 +2411,7 @@ class De extends H {
|
|
|
2411
2411
|
* @returns Transform data object
|
|
2412
2412
|
*/
|
|
2413
2413
|
extractTransformData(e, t, r) {
|
|
2414
|
-
const i = e[r], s = e[r + 1],
|
|
2414
|
+
const i = e[r], s = e[r + 1], o = e[r + 2], n = i === 255, l = s === 255, c = o === 255, u = t[r], d = t[r + 1], f = u + d / 255, g = Math.round(f * 360 / 255 * 100) / 100;
|
|
2415
2415
|
return {
|
|
2416
2416
|
isInverted: n,
|
|
2417
2417
|
flipHorizontal: l,
|
|
@@ -2445,7 +2445,7 @@ class De extends H {
|
|
|
2445
2445
|
const r = [];
|
|
2446
2446
|
let i = 0;
|
|
2447
2447
|
for (let s = 0; s < t.rows; s++)
|
|
2448
|
-
for (let
|
|
2448
|
+
for (let o = 0; o < t.cols; o++) {
|
|
2449
2449
|
const n = i * 4, l = this.getCharacterIndex(
|
|
2450
2450
|
e.characterPixels,
|
|
2451
2451
|
n
|
|
@@ -2460,7 +2460,7 @@ class De extends H {
|
|
|
2460
2460
|
const g = c;
|
|
2461
2461
|
c = u, u = g;
|
|
2462
2462
|
}
|
|
2463
|
-
const f = this.calculateCellPosition(
|
|
2463
|
+
const f = this.calculateCellPosition(o, s, t);
|
|
2464
2464
|
r.push({
|
|
2465
2465
|
charIndex: l,
|
|
2466
2466
|
primaryColor: c,
|
|
@@ -2489,9 +2489,9 @@ class Ae {
|
|
|
2489
2489
|
if (i.idRangeOffset[s] === 0)
|
|
2490
2490
|
return t + i.idDelta[s] & 65535;
|
|
2491
2491
|
{
|
|
2492
|
-
const
|
|
2493
|
-
if (
|
|
2494
|
-
const n = i.glyphIdArray[
|
|
2492
|
+
const o = i.idRangeOffset[s] / 2 + (t - i.startCount[s]) - (i.startCount.length - s);
|
|
2493
|
+
if (o >= 0 && o < i.glyphIdArray.length) {
|
|
2494
|
+
const n = i.glyphIdArray[o];
|
|
2495
2495
|
if (n !== 0)
|
|
2496
2496
|
return n + i.idDelta[s] & 65535;
|
|
2497
2497
|
}
|
|
@@ -2522,15 +2522,15 @@ class Ae {
|
|
|
2522
2522
|
createGlyphPath(e, t, r, i, s) {
|
|
2523
2523
|
if (!t || !t.xs || t.xs.length === 0)
|
|
2524
2524
|
return this.createEmptyPath();
|
|
2525
|
-
const
|
|
2525
|
+
const o = s / e.head.unitsPerEm;
|
|
2526
2526
|
return {
|
|
2527
2527
|
getBoundingBox: () => ({
|
|
2528
|
-
x1: r + t.xMin *
|
|
2529
|
-
y1: i + -t.yMax *
|
|
2530
|
-
x2: r + t.xMax *
|
|
2531
|
-
y2: i + -t.yMin *
|
|
2528
|
+
x1: r + t.xMin * o,
|
|
2529
|
+
y1: i + -t.yMax * o,
|
|
2530
|
+
x2: r + t.xMax * o,
|
|
2531
|
+
y2: i + -t.yMin * o
|
|
2532
2532
|
}),
|
|
2533
|
-
toSVG: () => this.glyphToSVGPath(t, r, i,
|
|
2533
|
+
toSVG: () => this.glyphToSVGPath(t, r, i, o)
|
|
2534
2534
|
};
|
|
2535
2535
|
}
|
|
2536
2536
|
/**
|
|
@@ -2543,28 +2543,28 @@ class Ae {
|
|
|
2543
2543
|
*/
|
|
2544
2544
|
glyphToSVGPath(e, t, r, i) {
|
|
2545
2545
|
if (!e || !e.xs) return "";
|
|
2546
|
-
const { xs: s, ys:
|
|
2547
|
-
if (!s || !
|
|
2546
|
+
const { xs: s, ys: o, endPts: n, flags: l } = e;
|
|
2547
|
+
if (!s || !o || !n || !l) return "";
|
|
2548
2548
|
let c = "", u = 0;
|
|
2549
2549
|
for (let d = 0; d < n.length; d++) {
|
|
2550
2550
|
const f = n[d];
|
|
2551
2551
|
if (!(f < u)) {
|
|
2552
2552
|
if (f >= u) {
|
|
2553
|
-
const g = t + s[u] * i, p = r -
|
|
2553
|
+
const g = t + s[u] * i, p = r - o[u] * i;
|
|
2554
2554
|
c += `M${g.toFixed(2)},${p.toFixed(2)}`;
|
|
2555
2555
|
let _ = u + 1;
|
|
2556
2556
|
for (; _ <= f; )
|
|
2557
2557
|
if ((l[_] & 1) !== 0) {
|
|
2558
|
-
const C = t + s[_] * i, v = r -
|
|
2558
|
+
const C = t + s[_] * i, v = r - o[_] * i;
|
|
2559
2559
|
c += `L${C.toFixed(2)},${v.toFixed(2)}`, _++;
|
|
2560
2560
|
} else {
|
|
2561
|
-
const C = t + s[_] * i, v = r -
|
|
2561
|
+
const C = t + s[_] * i, v = r - o[_] * i;
|
|
2562
2562
|
let w = _ + 1 > f ? u : _ + 1;
|
|
2563
2563
|
if ((l[w] & 1) !== 0) {
|
|
2564
|
-
const R = t + s[w] * i, y = r -
|
|
2564
|
+
const R = t + s[w] * i, y = r - o[w] * i;
|
|
2565
2565
|
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${R.toFixed(2)},${y.toFixed(2)}`, _ = w + 1;
|
|
2566
2566
|
} else {
|
|
2567
|
-
const R = t + s[w] * i, y = r -
|
|
2567
|
+
const R = t + s[w] * i, y = r - o[w] * i, P = (C + R) / 2, M = (v + y) / 2;
|
|
2568
2568
|
c += `Q${C.toFixed(2)},${v.toFixed(2)} ${P.toFixed(2)},${M.toFixed(2)}`, _ = w;
|
|
2569
2569
|
}
|
|
2570
2570
|
}
|
|
@@ -2586,7 +2586,7 @@ class Ae {
|
|
|
2586
2586
|
*/
|
|
2587
2587
|
generateCharacterPath(e, t, r, i, s) {
|
|
2588
2588
|
try {
|
|
2589
|
-
const
|
|
2589
|
+
const o = e.codePointAt(0) || 0, n = this.getGlyphIndex(t, o);
|
|
2590
2590
|
if (n === 0)
|
|
2591
2591
|
return this.createEmptyPath();
|
|
2592
2592
|
let l = null;
|
|
@@ -2596,8 +2596,8 @@ class Ae {
|
|
|
2596
2596
|
console.warn(`Failed to parse glyph ${n}:`, c);
|
|
2597
2597
|
}
|
|
2598
2598
|
return l ? this.createGlyphPath(t, l, r, i, s) : this.createEmptyPath();
|
|
2599
|
-
} catch (
|
|
2600
|
-
return console.warn(`Failed to generate path for character "${e}":`,
|
|
2599
|
+
} catch (o) {
|
|
2600
|
+
return console.warn(`Failed to generate path for character "${e}":`, o), this.createEmptyPath();
|
|
2601
2601
|
}
|
|
2602
2602
|
}
|
|
2603
2603
|
/**
|
|
@@ -2612,9 +2612,9 @@ class Ae {
|
|
|
2612
2612
|
* @param advanceWidth Character advance width
|
|
2613
2613
|
* @returns SVG path data string or null if generation fails
|
|
2614
2614
|
*/
|
|
2615
|
-
generatePositionedCharacterPath(e, t, r, i, s,
|
|
2615
|
+
generatePositionedCharacterPath(e, t, r, i, s, o, n, l) {
|
|
2616
2616
|
try {
|
|
2617
|
-
const c = n / t.head.unitsPerEm, u = l * c, d = r + (s - u) / 2, f = i + (
|
|
2617
|
+
const c = n / t.head.unitsPerEm, u = l * c, d = r + (s - u) / 2, f = i + (o + n * 0.7) / 2;
|
|
2618
2618
|
return this.generateCharacterPath(e, t, d, f, n).toSVG() || null;
|
|
2619
2619
|
} catch (c) {
|
|
2620
2620
|
return console.warn(`Failed to generate positioned character path for "${e}":`, c), null;
|
|
@@ -2623,7 +2623,7 @@ class Ae {
|
|
|
2623
2623
|
}
|
|
2624
2624
|
class Me {
|
|
2625
2625
|
constructor() {
|
|
2626
|
-
|
|
2626
|
+
a(this, "pathGenerator");
|
|
2627
2627
|
this.pathGenerator = new Ae();
|
|
2628
2628
|
}
|
|
2629
2629
|
/**
|
|
@@ -2676,12 +2676,12 @@ class Me {
|
|
|
2676
2676
|
* @returns Transform attribute string or empty string
|
|
2677
2677
|
*/
|
|
2678
2678
|
generateTransformAttribute(e, t) {
|
|
2679
|
-
const { transform: r, position: i } = e, s = i.cellX + t.cellWidth / 2,
|
|
2679
|
+
const { transform: r, position: i } = e, s = i.cellX + t.cellWidth / 2, o = i.cellY + t.cellHeight / 2, n = [];
|
|
2680
2680
|
if (r.flipHorizontal || r.flipVertical) {
|
|
2681
2681
|
const l = r.flipHorizontal ? -1 : 1, c = r.flipVertical ? -1 : 1;
|
|
2682
|
-
n.push(`translate(${s} ${
|
|
2682
|
+
n.push(`translate(${s} ${o})`), n.push(`scale(${l} ${c})`), n.push(`translate(${-s} ${-o})`);
|
|
2683
2683
|
}
|
|
2684
|
-
return r.rotation && n.push(`rotate(${r.rotation} ${s} ${
|
|
2684
|
+
return r.rotation && n.push(`rotate(${r.rotation} ${s} ${o})`), n.length ? ` transform="${n.join(" ")}"` : "";
|
|
2685
2685
|
}
|
|
2686
2686
|
/**
|
|
2687
2687
|
* Generates background rectangle for a cell
|
|
@@ -2710,7 +2710,7 @@ class Me {
|
|
|
2710
2710
|
const s = r.characters[e.charIndex];
|
|
2711
2711
|
if (!s)
|
|
2712
2712
|
return "";
|
|
2713
|
-
const
|
|
2713
|
+
const o = this.pathGenerator.generatePositionedCharacterPath(
|
|
2714
2714
|
s.character,
|
|
2715
2715
|
r.font,
|
|
2716
2716
|
e.position.cellX,
|
|
@@ -2720,12 +2720,12 @@ class Me {
|
|
|
2720
2720
|
r.fontSize,
|
|
2721
2721
|
s.advanceWidth
|
|
2722
2722
|
);
|
|
2723
|
-
if (!
|
|
2723
|
+
if (!o)
|
|
2724
2724
|
return "";
|
|
2725
2725
|
const n = this.rgbaToColorString(e.primaryColor);
|
|
2726
2726
|
return i.drawMode === "stroke" ? `
|
|
2727
|
-
<path id="${`path-${e.charIndex}-${e.position.cellX}-${e.position.cellY}`.replace(/\./g, "-")}" d="${
|
|
2728
|
-
<path d="${
|
|
2727
|
+
<path id="${`path-${e.charIndex}-${e.position.cellX}-${e.position.cellY}`.replace(/\./g, "-")}" d="${o}" stroke="${n}" stroke-width="${i.strokeWidth}" fill="none" />` : `
|
|
2728
|
+
<path d="${o}" fill="${n}" />`;
|
|
2729
2729
|
}
|
|
2730
2730
|
/**
|
|
2731
2731
|
* Generates complete SVG content for a single cell
|
|
@@ -2738,9 +2738,9 @@ class Me {
|
|
|
2738
2738
|
generateCellContent(e, t, r, i) {
|
|
2739
2739
|
let s = "";
|
|
2740
2740
|
s += this.generateCellBackground(e, t, i);
|
|
2741
|
-
const
|
|
2742
|
-
return n && (
|
|
2743
|
-
<g${
|
|
2741
|
+
const o = this.generateTransformAttribute(e, t), n = this.generateCharacterPath(e, t, r, i);
|
|
2742
|
+
return n && (o ? (s += `
|
|
2743
|
+
<g${o}>`, s += n, s += `
|
|
2744
2744
|
</g>`) : s += n), s;
|
|
2745
2745
|
}
|
|
2746
2746
|
/**
|
|
@@ -2755,8 +2755,8 @@ class Me {
|
|
|
2755
2755
|
let s = this.generateSVGHeader(t);
|
|
2756
2756
|
s += this.generateBackground(t, i), s += `
|
|
2757
2757
|
<g id="ascii-cells">`;
|
|
2758
|
-
for (const
|
|
2759
|
-
s += this.generateCellContent(
|
|
2758
|
+
for (const o of e)
|
|
2759
|
+
s += this.generateCellContent(o, t, r, i);
|
|
2760
2760
|
return s += this.generateSVGFooter(), s;
|
|
2761
2761
|
}
|
|
2762
2762
|
/**
|
|
@@ -2801,9 +2801,9 @@ class Ie extends N {
|
|
|
2801
2801
|
}
|
|
2802
2802
|
class Y {
|
|
2803
2803
|
constructor() {
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2804
|
+
a(this, "dataExtractor");
|
|
2805
|
+
a(this, "contentGenerator");
|
|
2806
|
+
a(this, "fileHandler");
|
|
2807
2807
|
this.dataExtractor = new De(), this.contentGenerator = new Me(), this.fileHandler = new Ie();
|
|
2808
2808
|
}
|
|
2809
2809
|
/**
|
|
@@ -2829,13 +2829,13 @@ class Y {
|
|
|
2829
2829
|
const r = this.applyDefaultOptions(t), i = this.dataExtractor.extractFramebufferData(e.pipeline), s = this.dataExtractor.extractSVGCellData(
|
|
2830
2830
|
i,
|
|
2831
2831
|
e.grid
|
|
2832
|
-
),
|
|
2832
|
+
), o = this.contentGenerator.generateSVGContent(
|
|
2833
2833
|
s,
|
|
2834
2834
|
e.grid,
|
|
2835
2835
|
e.font,
|
|
2836
2836
|
r
|
|
2837
2837
|
);
|
|
2838
|
-
return this.contentGenerator.optimizeSVGContent(
|
|
2838
|
+
return this.contentGenerator.optimizeSVGContent(o);
|
|
2839
2839
|
}
|
|
2840
2840
|
/**
|
|
2841
2841
|
* Exports SVG content to a downloadable file
|
|
@@ -2863,15 +2863,15 @@ class Pe extends H {
|
|
|
2863
2863
|
extractCharacterGrid(e, t, r, i = " ") {
|
|
2864
2864
|
var n;
|
|
2865
2865
|
const s = [];
|
|
2866
|
-
let
|
|
2866
|
+
let o = 0;
|
|
2867
2867
|
for (let l = 0; l < t.rows; l++) {
|
|
2868
2868
|
const c = [];
|
|
2869
2869
|
for (let u = 0; u < t.cols; u++) {
|
|
2870
|
-
const d =
|
|
2870
|
+
const d = o * 4, f = this.getCharacterIndex(
|
|
2871
2871
|
e.characterPixels,
|
|
2872
2872
|
d
|
|
2873
2873
|
), g = ((n = r.characters[f]) == null ? void 0 : n.character) || i;
|
|
2874
|
-
c.push(g),
|
|
2874
|
+
c.push(g), o++;
|
|
2875
2875
|
}
|
|
2876
2876
|
s.push(c);
|
|
2877
2877
|
}
|
|
@@ -2888,8 +2888,8 @@ class Be {
|
|
|
2888
2888
|
generateTXTContent(e, t) {
|
|
2889
2889
|
const r = [];
|
|
2890
2890
|
for (const s of e) {
|
|
2891
|
-
let
|
|
2892
|
-
t.preserveTrailingSpaces || (
|
|
2891
|
+
let o = s.join("");
|
|
2892
|
+
t.preserveTrailingSpaces || (o = o.replace(/\s+$/, "")), r.push(o);
|
|
2893
2893
|
}
|
|
2894
2894
|
const i = t.lineEnding === "crlf" ? `\r
|
|
2895
2895
|
` : `
|
|
@@ -2923,9 +2923,9 @@ class Ge extends N {
|
|
|
2923
2923
|
}
|
|
2924
2924
|
class j {
|
|
2925
2925
|
constructor() {
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2926
|
+
a(this, "dataExtractor");
|
|
2927
|
+
a(this, "contentGenerator");
|
|
2928
|
+
a(this, "fileHandler");
|
|
2929
2929
|
this.dataExtractor = new Pe(), this.contentGenerator = new Be(), this.fileHandler = new Ge();
|
|
2930
2930
|
}
|
|
2931
2931
|
/**
|
|
@@ -2984,8 +2984,8 @@ class Ve extends H {
|
|
|
2984
2984
|
const i = e.canvas;
|
|
2985
2985
|
if (t === 1 && r === "transparent")
|
|
2986
2986
|
return i;
|
|
2987
|
-
const s = document.createElement("canvas"),
|
|
2988
|
-
return s.width = n, s.height = l, r !== "transparent" && (
|
|
2987
|
+
const s = document.createElement("canvas"), o = s.getContext("2d"), n = Math.round(i.width * t), l = Math.round(i.height * t);
|
|
2988
|
+
return s.width = n, s.height = l, r !== "transparent" && (o.fillStyle = r, o.fillRect(0, 0, n, l)), o.imageSmoothingEnabled = !1, o.drawImage(
|
|
2989
2989
|
i,
|
|
2990
2990
|
0,
|
|
2991
2991
|
0,
|
|
@@ -3017,10 +3017,10 @@ class ke {
|
|
|
3017
3017
|
*/
|
|
3018
3018
|
async generateImageBlob(e, t) {
|
|
3019
3019
|
return new Promise((r, i) => {
|
|
3020
|
-
const s = this.getMimeType(t.format),
|
|
3020
|
+
const s = this.getMimeType(t.format), o = (n) => {
|
|
3021
3021
|
n ? r(n) : i(new Error(`Failed to generate ${t.format.toUpperCase()} blob`));
|
|
3022
3022
|
};
|
|
3023
|
-
t.format === "png" ? e.toBlob(
|
|
3023
|
+
t.format === "png" ? e.toBlob(o, s) : e.toBlob(o, s, t.quality);
|
|
3024
3024
|
});
|
|
3025
3025
|
}
|
|
3026
3026
|
/**
|
|
@@ -3115,9 +3115,9 @@ class ze extends N {
|
|
|
3115
3115
|
}
|
|
3116
3116
|
class $e {
|
|
3117
3117
|
constructor() {
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3118
|
+
a(this, "dataExtractor");
|
|
3119
|
+
a(this, "contentGenerator");
|
|
3120
|
+
a(this, "fileHandler");
|
|
3121
3121
|
this.dataExtractor = new Ve(), this.contentGenerator = new ke(), this.fileHandler = new ze();
|
|
3122
3122
|
}
|
|
3123
3123
|
/**
|
|
@@ -3204,37 +3204,38 @@ class $e {
|
|
|
3204
3204
|
class I {
|
|
3205
3205
|
constructor(e = null, t = {}) {
|
|
3206
3206
|
/** The element to capture content from (optional for standalone mode) */
|
|
3207
|
-
|
|
3207
|
+
a(this, "captureSource");
|
|
3208
3208
|
/** Our WebGL overlay canvas manager */
|
|
3209
|
-
|
|
3209
|
+
a(this, "textmodeCanvas");
|
|
3210
3210
|
/** Core WebGL renderer */
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3211
|
+
a(this, "_renderer");
|
|
3212
|
+
a(this, "_canvasFramebuffer");
|
|
3213
|
+
a(this, "_font");
|
|
3214
|
+
a(this, "_grid");
|
|
3215
|
+
a(this, "resizeObserver");
|
|
3216
3216
|
// Auto-rendering properties
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3217
|
+
a(this, "_mode");
|
|
3218
|
+
a(this, "_frameRateLimit");
|
|
3219
|
+
a(this, "animationFrameId", null);
|
|
3220
|
+
a(this, "lastFrameTime", 0);
|
|
3221
|
+
a(this, "frameInterval");
|
|
3222
|
+
a(this, "_isLooping", !0);
|
|
3223
|
+
a(this, "_frameRate", 0);
|
|
3224
|
+
a(this, "lastRenderTime", 0);
|
|
3225
|
+
a(this, "_frameCount", 0);
|
|
3225
3226
|
// Frame rate measurement smoothing
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3227
|
+
a(this, "frameTimeHistory", []);
|
|
3228
|
+
a(this, "frameTimeHistorySize", 10);
|
|
3229
|
+
a(this, "_pipeline");
|
|
3229
3230
|
// Standalone canvas properties
|
|
3230
|
-
|
|
3231
|
-
|
|
3231
|
+
a(this, "_standalone", !1);
|
|
3232
|
+
a(this, "_drawCallback", () => {
|
|
3232
3233
|
});
|
|
3233
|
-
|
|
3234
|
+
a(this, "_resizedCallback", () => {
|
|
3234
3235
|
});
|
|
3235
3236
|
// Destroy state
|
|
3236
|
-
|
|
3237
|
-
|
|
3237
|
+
a(this, "_isDestroyed", !1);
|
|
3238
|
+
a(this, "_windowResizeListener", null);
|
|
3238
3239
|
this.captureSource = e, this._standalone = e === null, this._mode = t.renderMode ?? "auto", this._frameRateLimit = t.frameRate ?? 60, this.frameInterval = 1e3 / this._frameRateLimit;
|
|
3239
3240
|
}
|
|
3240
3241
|
/**
|
|
@@ -3246,8 +3247,8 @@ class I {
|
|
|
3246
3247
|
static async create(e = null, t = {}) {
|
|
3247
3248
|
const r = new I(e, t), i = r._standalone ? t : void 0;
|
|
3248
3249
|
r.textmodeCanvas = new be(r.captureSource, r._standalone, i), r._renderer = new fe(r.textmodeCanvas.getWebGLContext());
|
|
3249
|
-
let s,
|
|
3250
|
-
r._standalone ? (s = t.width || 800,
|
|
3250
|
+
let s, o;
|
|
3251
|
+
r._standalone ? (s = t.width || 800, o = t.height || 600) : (s = r.textmodeCanvas.width || 800, o = r.textmodeCanvas.height || 600), r._canvasFramebuffer = r._renderer.createFramebuffer(s, o), r._font = new xe(r._renderer, t.fontSize ?? 16), await r._font.initialize(t.fontSource);
|
|
3251
3252
|
const n = r._font.maxGlyphDimensions;
|
|
3252
3253
|
return r._grid = new ve(r.textmodeCanvas.canvas, n.width, n.height), r._pipeline = new Ue(r._renderer, r._font, r._grid), r.setupEventListeners(), r.startAutoRendering(), r;
|
|
3253
3254
|
}
|
|
@@ -3497,13 +3498,17 @@ class I {
|
|
|
3497
3498
|
* Start automatic rendering
|
|
3498
3499
|
*/
|
|
3499
3500
|
startAutoRendering() {
|
|
3500
|
-
if (this._mode !== "auto" || this._isDestroyed) return;
|
|
3501
|
+
if (this._mode !== "auto" || this._isDestroyed || !this._isLooping) return;
|
|
3501
3502
|
this.lastFrameTime = performance.now();
|
|
3502
3503
|
const e = (t) => {
|
|
3503
3504
|
if (this._isDestroyed)
|
|
3504
3505
|
return;
|
|
3506
|
+
if (!this._isLooping) {
|
|
3507
|
+
this.animationFrameId = null;
|
|
3508
|
+
return;
|
|
3509
|
+
}
|
|
3505
3510
|
const r = t - this.lastFrameTime;
|
|
3506
|
-
r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), this._isDestroyed
|
|
3511
|
+
r >= this.frameInterval && (this.render(), this.lastFrameTime = t - r % this.frameInterval), !this._isDestroyed && this._isLooping && (this.animationFrameId = requestAnimationFrame(e));
|
|
3507
3512
|
};
|
|
3508
3513
|
this.animationFrameId = requestAnimationFrame(e);
|
|
3509
3514
|
}
|
|
@@ -3557,7 +3562,7 @@ class I {
|
|
|
3557
3562
|
console.warn("Cannot change render mode: Textmodifier instance has been destroyed");
|
|
3558
3563
|
return;
|
|
3559
3564
|
}
|
|
3560
|
-
this._mode !== e && (this.stopAutoRendering(), this._mode = e, e === "auto" && this.startAutoRendering());
|
|
3565
|
+
this._mode !== e && (this.stopAutoRendering(), this._mode = e, e === "auto" && this._isLooping && this.startAutoRendering());
|
|
3561
3566
|
}
|
|
3562
3567
|
/**
|
|
3563
3568
|
* Set the maximum frame rate for auto rendering. If called without arguments, returns the current measured frame rate.
|
|
@@ -3578,7 +3583,105 @@ class I {
|
|
|
3578
3583
|
frameRate(e) {
|
|
3579
3584
|
if (e === void 0)
|
|
3580
3585
|
return this._frameRate;
|
|
3581
|
-
this._frameRateLimit = e, this.frameInterval = 1e3 / e, this._mode === "auto" && (this.stopAutoRendering(), this.startAutoRendering());
|
|
3586
|
+
this._frameRateLimit = e, this.frameInterval = 1e3 / e, this._mode === "auto" && this._isLooping && (this.stopAutoRendering(), this.startAutoRendering());
|
|
3587
|
+
}
|
|
3588
|
+
/**
|
|
3589
|
+
* Stop the automatic rendering loop while keeping the render mode as 'auto'.
|
|
3590
|
+
*
|
|
3591
|
+
* This method pauses the render loop without changing the render mode, allowing
|
|
3592
|
+
* it to be resumed later with {@link loop}. This is useful for temporarily pausing
|
|
3593
|
+
* animation while maintaining the ability to restart it.
|
|
3594
|
+
*
|
|
3595
|
+
* **Note:** This only affects rendering when in `'auto'` mode. In `'manual'` mode,
|
|
3596
|
+
* this method has no effect since rendering is already controlled manually.
|
|
3597
|
+
*
|
|
3598
|
+
* @example
|
|
3599
|
+
* ```javascript
|
|
3600
|
+
* // Create a textmodifier instance in auto mode
|
|
3601
|
+
* const textmodifier = await textmode.create(canvas);
|
|
3602
|
+
*
|
|
3603
|
+
* // The render loop is running automatically
|
|
3604
|
+
* console.log(textmodifier.isLooping()); // true
|
|
3605
|
+
*
|
|
3606
|
+
* // Stop the automatic rendering loop
|
|
3607
|
+
* textmodifier.noLoop();
|
|
3608
|
+
* console.log(textmodifier.isLooping()); // false
|
|
3609
|
+
*
|
|
3610
|
+
* // Resume the automatic rendering loop
|
|
3611
|
+
* textmodifier.loop();
|
|
3612
|
+
* console.log(textmodifier.isLooping()); // true
|
|
3613
|
+
* ```
|
|
3614
|
+
*/
|
|
3615
|
+
noLoop() {
|
|
3616
|
+
if (this._isDestroyed) {
|
|
3617
|
+
console.warn("Cannot stop loop: Textmodifier instance has been destroyed");
|
|
3618
|
+
return;
|
|
3619
|
+
}
|
|
3620
|
+
this._isLooping && (this._isLooping = !1, this.animationFrameId && (cancelAnimationFrame(this.animationFrameId), this.animationFrameId = null));
|
|
3621
|
+
}
|
|
3622
|
+
/**
|
|
3623
|
+
* Resume the automatic rendering loop if it was stopped by {@link noLoop}.
|
|
3624
|
+
*
|
|
3625
|
+
* This method restarts the render loop when in `'auto'` mode. If the render mode
|
|
3626
|
+
* is `'manual'`, the loop state will be set but automatic rendering will not start
|
|
3627
|
+
* until the mode is changed back to `'auto'`.
|
|
3628
|
+
*
|
|
3629
|
+
* @example
|
|
3630
|
+
* ```javascript
|
|
3631
|
+
* // Create a textmodifier instance
|
|
3632
|
+
* const textmodifier = await textmode.create(canvas);
|
|
3633
|
+
*
|
|
3634
|
+
* // Stop the loop
|
|
3635
|
+
* textmodifier.noLoop();
|
|
3636
|
+
*
|
|
3637
|
+
* // Resume the loop
|
|
3638
|
+
* textmodifier.loop();
|
|
3639
|
+
*
|
|
3640
|
+
* // You can also use this pattern for conditional animation
|
|
3641
|
+
* if (someCondition) {
|
|
3642
|
+
* textmodifier.loop();
|
|
3643
|
+
* } else {
|
|
3644
|
+
* textmodifier.noLoop();
|
|
3645
|
+
* }
|
|
3646
|
+
* ```
|
|
3647
|
+
*/
|
|
3648
|
+
loop() {
|
|
3649
|
+
if (this._isDestroyed) {
|
|
3650
|
+
console.warn("Cannot start loop: Textmodifier instance has been destroyed");
|
|
3651
|
+
return;
|
|
3652
|
+
}
|
|
3653
|
+
this._isLooping || (this._isLooping = !0, this._mode === "auto" && this.startAutoRendering());
|
|
3654
|
+
}
|
|
3655
|
+
/**
|
|
3656
|
+
* Check whether the textmodifier is currently running the automatic render loop.
|
|
3657
|
+
*
|
|
3658
|
+
* Returns `true` when both the render mode is `'auto'` AND the loop is active.
|
|
3659
|
+
* Returns `false` when in `'manual'` mode or when {@link noLoop} has been called.
|
|
3660
|
+
*
|
|
3661
|
+
* @returns True if the automatic render loop is currently active, false otherwise.
|
|
3662
|
+
*
|
|
3663
|
+
* @example
|
|
3664
|
+
* ```javascript
|
|
3665
|
+
* const textmodifier = await textmode.create(canvas);
|
|
3666
|
+
*
|
|
3667
|
+
* // Check loop status in different states
|
|
3668
|
+
* console.log(textmodifier.isLooping()); // true (auto mode, looping)
|
|
3669
|
+
*
|
|
3670
|
+
* textmodifier.noLoop();
|
|
3671
|
+
* console.log(textmodifier.isLooping()); // false (auto mode, not looping)
|
|
3672
|
+
*
|
|
3673
|
+
* textmodifier.renderMode('manual');
|
|
3674
|
+
* console.log(textmodifier.isLooping()); // false (manual mode)
|
|
3675
|
+
*
|
|
3676
|
+
* textmodifier.renderMode('auto');
|
|
3677
|
+
* console.log(textmodifier.isLooping()); // false (auto mode, but loop was stopped)
|
|
3678
|
+
*
|
|
3679
|
+
* textmodifier.loop();
|
|
3680
|
+
* console.log(textmodifier.isLooping()); // true (auto mode, looping)
|
|
3681
|
+
* ```
|
|
3682
|
+
*/
|
|
3683
|
+
isLooping() {
|
|
3684
|
+
return this._isDestroyed ? !1 : this._mode === "auto" && this._isLooping;
|
|
3582
3685
|
}
|
|
3583
3686
|
/**
|
|
3584
3687
|
* Set the font size used for rendering.
|
|
@@ -4140,7 +4243,7 @@ class I {
|
|
|
4140
4243
|
destroy() {
|
|
4141
4244
|
this._isDestroyed || (this._isDestroyed = !0, this.stopAutoRendering(), this._windowResizeListener && (window.removeEventListener("resize", this._windowResizeListener), this._windowResizeListener = null), this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = null), this._pipeline && !this._pipeline.isDisposed && this._pipeline.dispose(), this._font && !this._font.isDisposed && this._font.dispose(), this._grid && !this._grid.isDisposed && this._grid.dispose(), this._canvasFramebuffer && !this._canvasFramebuffer.isDisposed && this._canvasFramebuffer.dispose(), this._renderer && !this._renderer.isDisposed && this._renderer.dispose(), this.textmodeCanvas && !this.textmodeCanvas.isDisposed && this.textmodeCanvas.dispose(), this.captureSource = null, this.textmodeCanvas = null, this._renderer = null, this._canvasFramebuffer = null, this._font = null, this._grid = null, this._pipeline = null, this.resizeObserver = null, this._drawCallback = () => {
|
|
4142
4245
|
}, this._resizedCallback = () => {
|
|
4143
|
-
}, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = []);
|
|
4246
|
+
}, this.animationFrameId = null, this.lastFrameTime = 0, this.lastRenderTime = 0, this._frameCount = 0, this._frameRate = 0, this.frameTimeHistory = [], this._isLooping = !1);
|
|
4144
4247
|
}
|
|
4145
4248
|
/** Get the current grid object used for rendering. */
|
|
4146
4249
|
get grid() {
|
|
@@ -4273,7 +4376,7 @@ class O {
|
|
|
4273
4376
|
* ```
|
|
4274
4377
|
*/
|
|
4275
4378
|
static get version() {
|
|
4276
|
-
return "0.1.4-beta.
|
|
4379
|
+
return "0.1.4-beta.2";
|
|
4277
4380
|
}
|
|
4278
4381
|
constructor() {
|
|
4279
4382
|
throw new Error("Textmode is a static class and cannot be instantiated.");
|