textmode.js 0.1.6-beta.1 → 0.1.6-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/textmode.esm.js +485 -431
- package/dist/textmode.esm.min.js +331 -277
- package/dist/textmode.umd.js +13 -13
- package/dist/textmode.umd.min.js +12 -12
- package/dist/types/rendering/webgl/Renderer.d.ts +2 -2
- package/dist/types/textmode/Canvas.d.ts +17 -0
- package/package.json +1 -1
package/dist/textmode.esm.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
var iA = Object.defineProperty;
|
|
2
|
-
var sA = (
|
|
3
|
-
var
|
|
4
|
-
class
|
|
2
|
+
var sA = (a, A, e) => A in a ? iA(a, A, { enumerable: !0, configurable: !0, writable: !0, value: e }) : a[A] = e;
|
|
3
|
+
var o = (a, A, e) => sA(a, typeof A != "symbol" ? A + "" : A, e);
|
|
4
|
+
class p extends Error {
|
|
5
5
|
constructor(e, t, r = {}) {
|
|
6
|
-
const i =
|
|
6
|
+
const i = p.createFormattedMessage(e, r);
|
|
7
7
|
super(i);
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
o(this, "originalError");
|
|
9
|
+
o(this, "context");
|
|
10
10
|
this.name = "TextmodeError", this.originalError = t, this.context = r;
|
|
11
11
|
}
|
|
12
12
|
/**
|
|
@@ -19,9 +19,9 @@ class P extends Error {
|
|
|
19
19
|
|
|
20
20
|
📋 Context:`;
|
|
21
21
|
for (const [i, s] of Object.entries(t)) {
|
|
22
|
-
const
|
|
22
|
+
const n = p.formatValue(s);
|
|
23
23
|
r += `
|
|
24
|
-
- ${i}: ${
|
|
24
|
+
- ${i}: ${n}`;
|
|
25
25
|
}
|
|
26
26
|
}
|
|
27
27
|
return r += `
|
|
@@ -38,24 +38,24 @@ class P extends Error {
|
|
|
38
38
|
if (typeof e == "string") return `"${e}"`;
|
|
39
39
|
if (typeof e == "number" || typeof e == "boolean") return String(e);
|
|
40
40
|
if (Array.isArray(e))
|
|
41
|
-
return e.length === 0 ? "[]" : e.length <= 5 ? `[${e.map((t) =>
|
|
41
|
+
return e.length === 0 ? "[]" : e.length <= 5 ? `[${e.map((t) => p.formatValue(t)).join(", ")}]` : `[${e.slice(0, 3).map((t) => p.formatValue(t)).join(", ")}, ... +${e.length - 3} more]`;
|
|
42
42
|
if (typeof e == "object") {
|
|
43
43
|
const t = Object.keys(e);
|
|
44
|
-
return t.length === 0 ? "{}" : t.length <= 3 ? `{ ${t.map((s) => `${s}: ${
|
|
44
|
+
return t.length === 0 ? "{}" : t.length <= 3 ? `{ ${t.map((s) => `${s}: ${p.formatValue(e[s])}`).join(", ")} }` : `{ ${t.slice(0, 2).map((i) => `${i}: ${p.formatValue(e[i])}`).join(", ")}, ... +${t.length - 2} more }`;
|
|
45
45
|
}
|
|
46
46
|
return String(e);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
var
|
|
50
|
-
const
|
|
49
|
+
var nA = /* @__PURE__ */ ((a) => (a[a.SILENT = 0] = "SILENT", a[a.WARNING = 1] = "WARNING", a[a.ERROR = 2] = "ERROR", a[a.THROW = 3] = "THROW", a))(nA || {});
|
|
50
|
+
const b = class b {
|
|
51
51
|
constructor() {
|
|
52
|
-
|
|
52
|
+
o(this, "_options", {
|
|
53
53
|
globalLevel: 3
|
|
54
54
|
/* THROW */
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
static getInstance() {
|
|
58
|
-
return
|
|
58
|
+
return b._instance || (b._instance = new b()), b._instance;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
61
|
* Handle an error based on the configured settings
|
|
@@ -71,15 +71,15 @@ const v = class v {
|
|
|
71
71
|
return console.group(
|
|
72
72
|
`%c${r} Oops! (╯°□°)╯︵ Something went wrong in your code.`,
|
|
73
73
|
"color: #f44336; font-weight: bold; background: #ffebee; padding: 2px 6px; border-radius: 3px;"
|
|
74
|
-
), console.warn(
|
|
74
|
+
), console.warn(p.createFormattedMessage(A, e)), console.groupEnd(), !1;
|
|
75
75
|
case 2:
|
|
76
76
|
return console.group(
|
|
77
77
|
`%c${r} Oops! (╯°□°)╯︵ Something went wrong in your code.`,
|
|
78
78
|
"color: #f44336; font-weight: bold; background: #ffebee; padding: 2px 6px; border-radius: 3px;"
|
|
79
|
-
), console.error(
|
|
79
|
+
), console.error(p.createFormattedMessage(A, e)), console.groupEnd(), !1;
|
|
80
80
|
case 3:
|
|
81
81
|
default:
|
|
82
|
-
const i = new
|
|
82
|
+
const i = new p(A, t, e);
|
|
83
83
|
throw console.group(
|
|
84
84
|
`%c${r} Oops! (╯°□°)╯︵ Something went wrong in your code.`,
|
|
85
85
|
"color: #d32f2f; font-weight: bold; background: #ffcdd2; padding: 2px 6px; border-radius: 3px;"
|
|
@@ -103,19 +103,19 @@ const v = class v {
|
|
|
103
103
|
this._options.globalLevel = A;
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
|
-
|
|
107
|
-
let V =
|
|
106
|
+
o(b, "_instance", null);
|
|
107
|
+
let V = b;
|
|
108
108
|
const f = V.getInstance();
|
|
109
|
-
class
|
|
109
|
+
class oA {
|
|
110
110
|
constructor(A, e, t = e, r = {}) {
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
o(this, "gl");
|
|
112
|
+
o(this, "_framebuffer");
|
|
113
|
+
o(this, "_texture");
|
|
114
|
+
o(this, "_width");
|
|
115
|
+
o(this, "_height");
|
|
116
|
+
o(this, "options");
|
|
117
|
+
o(this, "previousState", null);
|
|
118
|
+
o(this, "_pixels", null);
|
|
119
119
|
this.gl = A, this._width = e, this._height = t, this.options = {
|
|
120
120
|
filter: "nearest",
|
|
121
121
|
wrap: "clamp",
|
|
@@ -189,16 +189,16 @@ class aA {
|
|
|
189
189
|
get(A, e, t, r) {
|
|
190
190
|
const { gl: i } = this;
|
|
191
191
|
if (A === void 0 && e === void 0) {
|
|
192
|
-
const s = new Uint8Array(this._width * this._height * 4),
|
|
193
|
-
return i.bindFramebuffer(i.FRAMEBUFFER, this._framebuffer), i.readPixels(0, 0, this._width, this._height, i.RGBA, i.UNSIGNED_BYTE, s), i.bindFramebuffer(i.FRAMEBUFFER,
|
|
192
|
+
const s = new Uint8Array(this._width * this._height * 4), n = i.getParameter(i.FRAMEBUFFER_BINDING);
|
|
193
|
+
return i.bindFramebuffer(i.FRAMEBUFFER, this._framebuffer), i.readPixels(0, 0, this._width, this._height, i.RGBA, i.UNSIGNED_BYTE, s), i.bindFramebuffer(i.FRAMEBUFFER, n), s;
|
|
194
194
|
} else if (t === void 0 && r === void 0) {
|
|
195
195
|
(A < 0 || e < 0 || A >= this._width || e >= this._height) && (console.warn("The x and y values passed to Framebuffer.get are outside of its range and will be clamped."), A = Math.max(0, Math.min(A, this._width - 1)), e = Math.max(0, Math.min(e, this._height - 1)));
|
|
196
|
-
const s = new Uint8Array(4),
|
|
197
|
-
return i.bindFramebuffer(i.FRAMEBUFFER, this._framebuffer), i.readPixels(A, e, 1, 1, i.RGBA, i.UNSIGNED_BYTE, s), i.bindFramebuffer(i.FRAMEBUFFER,
|
|
196
|
+
const s = new Uint8Array(4), n = i.getParameter(i.FRAMEBUFFER_BINDING);
|
|
197
|
+
return i.bindFramebuffer(i.FRAMEBUFFER, this._framebuffer), i.readPixels(A, e, 1, 1, i.RGBA, i.UNSIGNED_BYTE, s), i.bindFramebuffer(i.FRAMEBUFFER, n), [s[0], s[1], s[2], s[3]];
|
|
198
198
|
} else {
|
|
199
199
|
A = Math.max(0, Math.min(A, this._width - 1)), e = Math.max(0, Math.min(e, this._height - 1)), t = Math.max(1, Math.min(t, this._width - A)), r = Math.max(1, Math.min(r, this._height - e));
|
|
200
|
-
const s = new Uint8Array(t * r * 4),
|
|
201
|
-
return i.bindFramebuffer(i.FRAMEBUFFER, this._framebuffer), i.readPixels(A, e, t, r, i.RGBA, i.UNSIGNED_BYTE, s), i.bindFramebuffer(i.FRAMEBUFFER,
|
|
200
|
+
const s = new Uint8Array(t * r * 4), n = i.getParameter(i.FRAMEBUFFER_BINDING);
|
|
201
|
+
return i.bindFramebuffer(i.FRAMEBUFFER, this._framebuffer), i.readPixels(A, e, t, r, i.RGBA, i.UNSIGNED_BYTE, s), i.bindFramebuffer(i.FRAMEBUFFER, n), s;
|
|
202
202
|
}
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
@@ -227,28 +227,28 @@ class aA {
|
|
|
227
227
|
}
|
|
228
228
|
class K {
|
|
229
229
|
constructor(A, e, t) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
230
|
+
o(this, "gl");
|
|
231
|
+
o(this, "x");
|
|
232
|
+
o(this, "y");
|
|
233
233
|
this.gl = A, this.x = e, this.y = t;
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
class y {
|
|
237
237
|
constructor(A, e, t, r, i) {
|
|
238
238
|
/** The WebGL rendering context */
|
|
239
|
-
|
|
239
|
+
o(this, "gl");
|
|
240
240
|
/** The vertex buffer containing position and texture coordinates */
|
|
241
|
-
|
|
241
|
+
o(this, "vertexBuffer");
|
|
242
242
|
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
243
|
-
|
|
243
|
+
o(this, "vertexCount", 6);
|
|
244
244
|
/** Bytes per vertex: depends on position format (vec2 vs vec3) */
|
|
245
|
-
|
|
245
|
+
o(this, "bytesPerVertex");
|
|
246
246
|
this.gl = A, this.bytesPerVertex = 16;
|
|
247
|
-
const s = A.getParameter(A.VIEWPORT),
|
|
248
|
-
let
|
|
249
|
-
B ? (
|
|
247
|
+
const s = A.getParameter(A.VIEWPORT), n = s[2], g = s[3], B = A.getParameter(A.FRAMEBUFFER_BINDING) !== null, h = e / n * 2 - 1, E = (e + r) / n * 2 - 1;
|
|
248
|
+
let l, c;
|
|
249
|
+
B ? (l = t / g * 2 - 1, c = (t + i) / g * 2 - 1) : (l = 1 - t / g * 2, c = 1 - (t + i) / g * 2);
|
|
250
250
|
let d, u, m, D;
|
|
251
|
-
d =
|
|
251
|
+
d = h, m = E, u = l, D = c;
|
|
252
252
|
const C = this.generateVertices(d, u, m, D);
|
|
253
253
|
this.vertexBuffer = A.createBuffer(), A.bindBuffer(A.ARRAY_BUFFER, this.vertexBuffer), A.bufferData(A.ARRAY_BUFFER, C, A.STATIC_DRAW);
|
|
254
254
|
}
|
|
@@ -300,11 +300,11 @@ class y {
|
|
|
300
300
|
this.gl.enableVertexAttribArray(e), this.gl.vertexAttribPointer(e, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 0), this.gl.enableVertexAttribArray(t), this.gl.vertexAttribPointer(t, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 8), this.gl.drawArrays(this.gl.TRIANGLES, 0, this.vertexCount), this.gl.disableVertexAttribArray(e), this.gl.disableVertexAttribArray(t);
|
|
301
301
|
}
|
|
302
302
|
}
|
|
303
|
-
class
|
|
303
|
+
class aA extends K {
|
|
304
304
|
constructor(e, t, r, i, s) {
|
|
305
305
|
super(e, t, r);
|
|
306
|
-
|
|
307
|
-
|
|
306
|
+
o(this, "width");
|
|
307
|
+
o(this, "height");
|
|
308
308
|
this.width = i, this.height = s;
|
|
309
309
|
}
|
|
310
310
|
/**
|
|
@@ -327,28 +327,28 @@ class nA extends K {
|
|
|
327
327
|
class gA {
|
|
328
328
|
constructor(A, e, t, r, i, s) {
|
|
329
329
|
/** The WebGL rendering context */
|
|
330
|
-
|
|
330
|
+
o(this, "gl");
|
|
331
331
|
/** The vertex buffer containing position and texture coordinates */
|
|
332
|
-
|
|
332
|
+
o(this, "vertexBuffer");
|
|
333
333
|
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
334
|
-
|
|
334
|
+
o(this, "vertexCount", 6);
|
|
335
335
|
/** Bytes per vertex: vec2+vec2 = 16 bytes */
|
|
336
|
-
|
|
336
|
+
o(this, "bytesPerVertex");
|
|
337
337
|
this.gl = A, this.bytesPerVertex = 16;
|
|
338
|
-
const
|
|
338
|
+
const n = A.getParameter(A.VIEWPORT), g = n[2], B = n[3], h = A.getParameter(A.FRAMEBUFFER_BINDING) !== null, E = r - e, l = i - t, c = Math.sqrt(E * E + l * l);
|
|
339
339
|
if (c === 0) {
|
|
340
340
|
const rA = this.generateVertices(0, 0, 0, 0);
|
|
341
341
|
this.vertexBuffer = A.createBuffer(), A.bindBuffer(A.ARRAY_BUFFER, this.vertexBuffer), A.bufferData(A.ARRAY_BUFFER, rA, A.STATIC_DRAW);
|
|
342
342
|
return;
|
|
343
343
|
}
|
|
344
|
-
const d =
|
|
345
|
-
let
|
|
346
|
-
|
|
344
|
+
const d = E / c, m = -(l / c), D = d, C = s / 2, P = e + m * C, F = t + D * C, v = e - m * C, I = t - D * C, R = r + m * C, T = i + D * C, j = r - m * C, W = i - D * C, Z = P / g * 2 - 1, q = v / g * 2 - 1, AA = R / g * 2 - 1, eA = j / g * 2 - 1;
|
|
345
|
+
let M, G, U, Y;
|
|
346
|
+
h ? (M = F / B * 2 - 1, G = I / B * 2 - 1, U = T / B * 2 - 1, Y = W / B * 2 - 1) : (M = 1 - F / B * 2, G = 1 - I / B * 2, U = 1 - T / B * 2, Y = 1 - W / B * 2);
|
|
347
347
|
const tA = this.generateLineVertices(
|
|
348
348
|
Z,
|
|
349
|
-
G,
|
|
350
|
-
q,
|
|
351
349
|
M,
|
|
350
|
+
q,
|
|
351
|
+
G,
|
|
352
352
|
AA,
|
|
353
353
|
U,
|
|
354
354
|
eA,
|
|
@@ -399,7 +399,7 @@ class gA {
|
|
|
399
399
|
* Uses the four corners calculated based on line direction and thickness
|
|
400
400
|
* @private
|
|
401
401
|
*/
|
|
402
|
-
generateLineVertices(A, e, t, r, i, s,
|
|
402
|
+
generateLineVertices(A, e, t, r, i, s, n, g) {
|
|
403
403
|
return new Float32Array([
|
|
404
404
|
A,
|
|
405
405
|
e,
|
|
@@ -421,7 +421,7 @@ class gA {
|
|
|
421
421
|
0,
|
|
422
422
|
1,
|
|
423
423
|
// corner2 (start - perpendicular)
|
|
424
|
-
|
|
424
|
+
n,
|
|
425
425
|
g,
|
|
426
426
|
1,
|
|
427
427
|
1,
|
|
@@ -446,8 +446,8 @@ class gA {
|
|
|
446
446
|
class BA extends K {
|
|
447
447
|
constructor(e, t, r, i, s) {
|
|
448
448
|
super(e, t, r);
|
|
449
|
-
|
|
450
|
-
|
|
449
|
+
o(this, "x2");
|
|
450
|
+
o(this, "y2");
|
|
451
451
|
this.x2 = i, this.y2 = s;
|
|
452
452
|
}
|
|
453
453
|
/**
|
|
@@ -465,13 +465,13 @@ class BA extends K {
|
|
|
465
465
|
new gA(this.gl, this.x, this.y, this.x2, this.y2, e).render();
|
|
466
466
|
}
|
|
467
467
|
}
|
|
468
|
-
class
|
|
468
|
+
class w {
|
|
469
469
|
constructor(A, e, t) {
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
470
|
+
o(this, "gl");
|
|
471
|
+
o(this, "program");
|
|
472
|
+
o(this, "uniformLocations", /* @__PURE__ */ new Map());
|
|
473
|
+
o(this, "attributeLocations", /* @__PURE__ */ new Map());
|
|
474
|
+
o(this, "textureUnitCounter", 0);
|
|
475
475
|
this.gl = A, this.program = this.createProgram(e, t), this.cacheLocations();
|
|
476
476
|
}
|
|
477
477
|
createProgram(A, e) {
|
|
@@ -612,26 +612,26 @@ class I {
|
|
|
612
612
|
this.textureUnitCounter = 0;
|
|
613
613
|
}
|
|
614
614
|
}
|
|
615
|
-
var
|
|
616
|
-
class
|
|
615
|
+
var _ = "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);}", hA = "precision lowp float;uniform sampler2D u_texture;varying vec2 v_uv;void main(){gl_FragColor=texture2D(u_texture,v_uv);}", EA = "precision lowp float;uniform vec4 u_color;void main(){gl_FragColor=u_color;}";
|
|
616
|
+
class lA {
|
|
617
617
|
constructor(A) {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
618
|
+
o(this, "gl");
|
|
619
|
+
o(this, "imageShader");
|
|
620
|
+
o(this, "solidColorShader");
|
|
621
|
+
o(this, "currentShader", null);
|
|
622
622
|
// Fill state management - default: white fill enabled
|
|
623
|
-
|
|
624
|
-
|
|
623
|
+
o(this, "currentFillColor", [1, 1, 1, 1]);
|
|
624
|
+
o(this, "fillMode", !0);
|
|
625
625
|
// Stroke state management - default: black stroke enabled, weight 1
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
626
|
+
o(this, "currentStrokeColor", [0, 0, 0, 1]);
|
|
627
|
+
o(this, "currentStrokeWeight", 1);
|
|
628
|
+
o(this, "strokeMode", !0);
|
|
629
629
|
// Transformation state management
|
|
630
|
-
|
|
630
|
+
o(this, "currentRotation", 0);
|
|
631
631
|
// in degrees
|
|
632
632
|
// State stack for push/pop functionality
|
|
633
|
-
|
|
634
|
-
this.gl = A, this.imageShader = new
|
|
633
|
+
o(this, "stateStack", []);
|
|
634
|
+
this.gl = A, this.imageShader = new w(this.gl, _, hA), this.solidColorShader = new w(this.gl, _, EA), 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);
|
|
635
635
|
}
|
|
636
636
|
/**
|
|
637
637
|
* Set the current shader
|
|
@@ -732,10 +732,10 @@ class hA {
|
|
|
732
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;
|
|
733
733
|
}
|
|
734
734
|
createShader(A, e) {
|
|
735
|
-
return new
|
|
735
|
+
return new w(this.gl, A, e);
|
|
736
736
|
}
|
|
737
737
|
createFilterShader(A) {
|
|
738
|
-
return new
|
|
738
|
+
return new w(this.gl, _, A);
|
|
739
739
|
}
|
|
740
740
|
/**
|
|
741
741
|
* Set a uniform value for the current shader
|
|
@@ -747,18 +747,18 @@ class hA {
|
|
|
747
747
|
* Draw a rectangle with the current fill and/or stroke settings
|
|
748
748
|
*/
|
|
749
749
|
rect(A, e, t, r) {
|
|
750
|
-
const i = new
|
|
750
|
+
const i = new aA(this.gl, A, e, t, r);
|
|
751
751
|
if (this.currentShader !== null) {
|
|
752
752
|
if (this.currentRotation !== 0) {
|
|
753
|
-
const { centerX:
|
|
754
|
-
this.setUniform("u_rotation", c), this.setUniform("u_center", [
|
|
753
|
+
const { centerX: E, centerY: l, radians: c, aspectRatio: d } = this.calculateRotationParams(A, e, t, r);
|
|
754
|
+
this.setUniform("u_rotation", c), this.setUniform("u_center", [E, l]), this.setUniform("u_aspectRatio", d);
|
|
755
755
|
} else
|
|
756
756
|
this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
|
|
757
757
|
i.renderFill(), this.currentShader = null;
|
|
758
758
|
return;
|
|
759
759
|
}
|
|
760
|
-
const s = this.solidColorShader, { centerX:
|
|
761
|
-
this.fillMode && (this.shader(s), this.setUniform("u_color", this.currentFillColor), this.setUniform("u_rotation", B), this.setUniform("u_center", [
|
|
760
|
+
const s = this.solidColorShader, { centerX: n, centerY: g, radians: B, aspectRatio: h } = this.calculateRotationParams(A, e, t, r);
|
|
761
|
+
this.fillMode && (this.shader(s), this.setUniform("u_color", this.currentFillColor), this.setUniform("u_rotation", B), this.setUniform("u_center", [n, g]), this.setUniform("u_aspectRatio", h), i.renderFill()), this.strokeMode && (this.shader(s), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", B), this.setUniform("u_center", [n, g]), this.setUniform("u_aspectRatio", h), i.renderStroke(this.currentStrokeWeight)), this.currentShader = null;
|
|
762
762
|
}
|
|
763
763
|
/**
|
|
764
764
|
* Draw a line from (x1, y1) to (x2, y2) with the current stroke settings.
|
|
@@ -773,31 +773,31 @@ class hA {
|
|
|
773
773
|
const i = new BA(this.gl, A, e, t, r);
|
|
774
774
|
if (this.currentShader !== null) {
|
|
775
775
|
if (this.currentRotation !== 0) {
|
|
776
|
-
const u = (A + t) / 2, m = (e + r) / 2, D = Math.abs(t - A), C = Math.abs(r - e), { centerX:
|
|
777
|
-
this.setUniform("u_rotation",
|
|
776
|
+
const u = (A + t) / 2, m = (e + r) / 2, D = Math.abs(t - A), C = Math.abs(r - e), { centerX: P, centerY: F, radians: v, aspectRatio: I } = this.calculateRotationParams(u - D / 2, m - C / 2, D, C);
|
|
777
|
+
this.setUniform("u_rotation", v), this.setUniform("u_center", [P, F]), this.setUniform("u_aspectRatio", I);
|
|
778
778
|
} else
|
|
779
779
|
this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
|
|
780
780
|
i.renderStroke(this.currentStrokeWeight), this.currentShader = null;
|
|
781
781
|
return;
|
|
782
782
|
}
|
|
783
|
-
const s = this.solidColorShader,
|
|
784
|
-
this.shader(s), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [
|
|
783
|
+
const s = this.solidColorShader, n = (A + t) / 2, g = (e + r) / 2, B = Math.abs(t - A), h = Math.abs(r - e), { centerX: E, centerY: l, radians: c, aspectRatio: d } = this.calculateRotationParams(n - B / 2, g - h / 2, B, h);
|
|
784
|
+
this.shader(s), this.setUniform("u_color", this.currentStrokeColor), this.setUniform("u_rotation", c), this.setUniform("u_center", [E, l]), this.setUniform("u_aspectRatio", d), i.renderStroke(this.currentStrokeWeight), this.currentShader = null;
|
|
785
785
|
}
|
|
786
786
|
/**
|
|
787
787
|
* Calculate rotation parameters for built-in shaders (NDC coordinates)
|
|
788
788
|
*/
|
|
789
789
|
calculateRotationParams(A, e, t, r) {
|
|
790
|
-
const i = this.gl.getParameter(this.gl.VIEWPORT), s = i[2],
|
|
790
|
+
const i = this.gl.getParameter(this.gl.VIEWPORT), s = i[2], n = i[3], g = s / n, B = this.gl.getParameter(this.gl.FRAMEBUFFER_BINDING) !== null, h = A + t / 2, E = e + r / 2, l = h / s * 2 - 1;
|
|
791
791
|
let c;
|
|
792
|
-
B ? c =
|
|
792
|
+
B ? c = E / n * 2 - 1 : c = 1 - E / n * 2;
|
|
793
793
|
const d = this.currentRotation * Math.PI / 180;
|
|
794
|
-
return { centerX:
|
|
794
|
+
return { centerX: l, centerY: c, radians: d, aspectRatio: g };
|
|
795
795
|
}
|
|
796
796
|
/**
|
|
797
797
|
* Create a new framebuffer
|
|
798
798
|
*/
|
|
799
799
|
createFramebuffer(A, e, t = {}) {
|
|
800
|
-
return new
|
|
800
|
+
return new oA(this.gl, A, e, t);
|
|
801
801
|
}
|
|
802
802
|
/**
|
|
803
803
|
* Fill the current framebuffer with a solid color
|
|
@@ -812,10 +812,11 @@ class hA {
|
|
|
812
812
|
this.gl.clearColor(A, e, t, r), this.gl.clear(this.gl.COLOR_BUFFER_BIT);
|
|
813
813
|
}
|
|
814
814
|
/**
|
|
815
|
-
* Ensure viewport matches canvas dimensions
|
|
815
|
+
* Ensure viewport matches canvas dimensions, optionally using custom dimensions for CSS transforms
|
|
816
816
|
*/
|
|
817
|
-
resetViewport() {
|
|
818
|
-
|
|
817
|
+
resetViewport(A, e) {
|
|
818
|
+
const t = A || this.gl.canvas.width, r = e || this.gl.canvas.height;
|
|
819
|
+
this.gl.viewport(0, 0, t, r);
|
|
819
820
|
}
|
|
820
821
|
/**
|
|
821
822
|
* Get the WebGL context
|
|
@@ -835,19 +836,19 @@ class hA {
|
|
|
835
836
|
*/
|
|
836
837
|
image(A, e, t, r, i) {
|
|
837
838
|
this.shader(this.imageShader), this.setUniform("u_texture", A.texture);
|
|
838
|
-
const { centerX: s, centerY:
|
|
839
|
+
const { centerX: s, centerY: n, radians: g, aspectRatio: B } = this.calculateRotationParams(
|
|
839
840
|
e,
|
|
840
841
|
t,
|
|
841
842
|
r ?? A.width,
|
|
842
843
|
i ?? A.height
|
|
843
844
|
);
|
|
844
|
-
this.setUniform("u_rotation", g), this.setUniform("u_center", [s,
|
|
845
|
+
this.setUniform("u_rotation", g), this.setUniform("u_center", [s, n]), this.setUniform("u_aspectRatio", B), this.rect(e, t, r ?? A.width, i ?? A.height);
|
|
845
846
|
}
|
|
846
847
|
}
|
|
847
848
|
var Q = {};
|
|
848
|
-
Q.parse = function(
|
|
849
|
-
var A = function(i, s,
|
|
850
|
-
var B = Q.T,
|
|
849
|
+
Q.parse = function(a) {
|
|
850
|
+
var A = function(i, s, n, g) {
|
|
851
|
+
var B = Q.T, h = {
|
|
851
852
|
cmap: B.cmap,
|
|
852
853
|
head: B.head,
|
|
853
854
|
hhea: B.hhea,
|
|
@@ -855,119 +856,119 @@ Q.parse = function(n) {
|
|
|
855
856
|
hmtx: B.hmtx,
|
|
856
857
|
loca: B.loca,
|
|
857
858
|
glyf: B.glyf
|
|
858
|
-
},
|
|
859
|
-
for (var
|
|
860
|
-
var c = Q.findTable(i,
|
|
859
|
+
}, E = { _data: i, _index: s, _offset: n };
|
|
860
|
+
for (var l in h) {
|
|
861
|
+
var c = Q.findTable(i, l, n);
|
|
861
862
|
if (c) {
|
|
862
863
|
var d = c[0], u = g[d];
|
|
863
|
-
u == null && (u =
|
|
864
|
+
u == null && (u = h[l].parseTab(i, d, c[1], E)), E[l] = g[d] = u;
|
|
864
865
|
}
|
|
865
866
|
}
|
|
866
|
-
return
|
|
867
|
-
}, e = new Uint8Array(
|
|
867
|
+
return E;
|
|
868
|
+
}, e = new Uint8Array(a), t = {}, r = A(e, 0, 0, t);
|
|
868
869
|
return [r];
|
|
869
870
|
};
|
|
870
|
-
Q.findTable = function(
|
|
871
|
-
for (var t = Q.B, r = t.readUshort(
|
|
872
|
-
var
|
|
873
|
-
t.readUint(
|
|
874
|
-
var g = t.readUint(
|
|
875
|
-
if (
|
|
871
|
+
Q.findTable = function(a, A, e) {
|
|
872
|
+
for (var t = Q.B, r = t.readUshort(a, e + 4), i = e + 12, s = 0; s < r; s++) {
|
|
873
|
+
var n = t.readASCII(a, i, 4);
|
|
874
|
+
t.readUint(a, i + 4);
|
|
875
|
+
var g = t.readUint(a, i + 8), B = t.readUint(a, i + 12);
|
|
876
|
+
if (n == A) return [g, B];
|
|
876
877
|
i += 16;
|
|
877
878
|
}
|
|
878
879
|
return null;
|
|
879
880
|
};
|
|
880
881
|
Q.T = {};
|
|
881
882
|
Q.B = {
|
|
882
|
-
readShort: function(
|
|
883
|
+
readShort: function(a, A) {
|
|
883
884
|
var e = Q.B.t.uint16;
|
|
884
|
-
return e[0] =
|
|
885
|
+
return e[0] = a[A] << 8 | a[A + 1], Q.B.t.int16[0];
|
|
885
886
|
},
|
|
886
|
-
readUshort: function(
|
|
887
|
-
return
|
|
887
|
+
readUshort: function(a, A) {
|
|
888
|
+
return a[A] << 8 | a[A + 1];
|
|
888
889
|
},
|
|
889
|
-
readUshorts: function(
|
|
890
|
+
readUshorts: function(a, A, e) {
|
|
890
891
|
for (var t = [], r = 0; r < e; r++)
|
|
891
|
-
t.push(Q.B.readUshort(
|
|
892
|
+
t.push(Q.B.readUshort(a, A + r * 2));
|
|
892
893
|
return t;
|
|
893
894
|
},
|
|
894
|
-
readUint: function(
|
|
895
|
+
readUint: function(a, A) {
|
|
895
896
|
var e = Q.B.t.uint8;
|
|
896
|
-
return e[3] =
|
|
897
|
+
return e[3] = a[A], e[2] = a[A + 1], e[1] = a[A + 2], e[0] = a[A + 3], Q.B.t.uint32[0];
|
|
897
898
|
},
|
|
898
|
-
readASCII: function(
|
|
899
|
-
for (var t = "", r = 0; r < e; r++) t += String.fromCharCode(
|
|
899
|
+
readASCII: function(a, A, e) {
|
|
900
|
+
for (var t = "", r = 0; r < e; r++) t += String.fromCharCode(a[A + r]);
|
|
900
901
|
return t;
|
|
901
902
|
},
|
|
902
903
|
// Simplified typed array buffer - only what's needed
|
|
903
904
|
t: function() {
|
|
904
|
-
var
|
|
905
|
+
var a = new ArrayBuffer(8);
|
|
905
906
|
return {
|
|
906
|
-
uint8: new Uint8Array(
|
|
907
|
-
int16: new Int16Array(
|
|
908
|
-
uint16: new Uint16Array(
|
|
909
|
-
uint32: new Uint32Array(
|
|
907
|
+
uint8: new Uint8Array(a),
|
|
908
|
+
int16: new Int16Array(a),
|
|
909
|
+
uint16: new Uint16Array(a),
|
|
910
|
+
uint32: new Uint32Array(a)
|
|
910
911
|
};
|
|
911
912
|
}()
|
|
912
913
|
};
|
|
913
914
|
Q.T.cmap = {
|
|
914
|
-
parseTab: function(
|
|
915
|
+
parseTab: function(a, A, e) {
|
|
915
916
|
var t = { tables: [], ids: {}, off: A };
|
|
916
|
-
|
|
917
|
+
a = new Uint8Array(a.buffer, A, e), A = 0;
|
|
917
918
|
var r = Q.B, i = r.readUshort, s = Q.T.cmap;
|
|
918
|
-
i(
|
|
919
|
-
var
|
|
919
|
+
i(a, A), A += 2;
|
|
920
|
+
var n = i(a, A);
|
|
920
921
|
A += 2;
|
|
921
|
-
for (var g = [], B = 0; B <
|
|
922
|
-
var
|
|
922
|
+
for (var g = [], B = 0; B < n; B++) {
|
|
923
|
+
var h = i(a, A);
|
|
923
924
|
A += 2;
|
|
924
|
-
var
|
|
925
|
+
var E = i(a, A);
|
|
925
926
|
A += 2;
|
|
926
|
-
var
|
|
927
|
+
var l = r.readUint(a, A);
|
|
927
928
|
A += 4;
|
|
928
|
-
var c = "p" +
|
|
929
|
+
var c = "p" + h + "e" + E, d = g.indexOf(l);
|
|
929
930
|
if (d == -1) {
|
|
930
931
|
d = t.tables.length;
|
|
931
932
|
var u = {};
|
|
932
|
-
g.push(
|
|
933
|
-
var m = u.format = i(
|
|
934
|
-
m == 4 ? u = s.parse4(
|
|
933
|
+
g.push(l);
|
|
934
|
+
var m = u.format = i(a, l);
|
|
935
|
+
m == 4 ? u = s.parse4(a, l, u) : m == 12 && (u = s.parse12(a, l, u)), t.tables.push(u);
|
|
935
936
|
}
|
|
936
937
|
t.ids[c] != null && console.log("multiple tables for one platform+encoding: " + c), t.ids[c] = d;
|
|
937
938
|
}
|
|
938
939
|
return t;
|
|
939
940
|
},
|
|
940
|
-
parse4: function(
|
|
941
|
+
parse4: function(a, A, e) {
|
|
941
942
|
var t = Q.B, r = t.readUshort, i = t.readUshorts, s = A;
|
|
942
943
|
A += 2;
|
|
943
|
-
var
|
|
944
|
-
A += 2, r(
|
|
945
|
-
var g = r(
|
|
944
|
+
var n = r(a, A);
|
|
945
|
+
A += 2, r(a, A), A += 2;
|
|
946
|
+
var g = r(a, A);
|
|
946
947
|
A += 2;
|
|
947
948
|
var B = g >>> 1;
|
|
948
|
-
e.searchRange = r(
|
|
949
|
-
for (var
|
|
950
|
-
e.idDelta.push(t.readShort(
|
|
951
|
-
return e.idRangeOffset = i(
|
|
949
|
+
e.searchRange = r(a, A), A += 2, e.entrySelector = r(a, A), A += 2, e.rangeShift = r(a, A), A += 2, e.endCount = i(a, A, B), A += B * 2, A += 2, e.startCount = i(a, A, B), A += B * 2, e.idDelta = [];
|
|
950
|
+
for (var h = 0; h < B; h++)
|
|
951
|
+
e.idDelta.push(t.readShort(a, A)), A += 2;
|
|
952
|
+
return e.idRangeOffset = i(a, A, B), A += B * 2, e.glyphIdArray = i(a, A, s + n - A >> 1), e;
|
|
952
953
|
},
|
|
953
|
-
parse12: function(
|
|
954
|
+
parse12: function(a, A, e) {
|
|
954
955
|
var t = Q.B, r = t.readUint;
|
|
955
|
-
A += 4, r(
|
|
956
|
-
var i = r(
|
|
956
|
+
A += 4, r(a, A), A += 4, r(a, A), A += 4;
|
|
957
|
+
var i = r(a, A) * 3;
|
|
957
958
|
A += 4;
|
|
958
|
-
for (var s = e.groups = new Uint32Array(i),
|
|
959
|
-
s[
|
|
959
|
+
for (var s = e.groups = new Uint32Array(i), n = 0; n < i; n += 3)
|
|
960
|
+
s[n] = r(a, A + (n << 2)), s[n + 1] = r(a, A + (n << 2) + 4), s[n + 2] = r(a, A + (n << 2) + 8);
|
|
960
961
|
return e;
|
|
961
962
|
}
|
|
962
963
|
};
|
|
963
964
|
Q.T.head = {
|
|
964
|
-
parseTab: function(
|
|
965
|
+
parseTab: function(a, A, e) {
|
|
965
966
|
var t = Q.B, r = {};
|
|
966
|
-
return A += 18, r.unitsPerEm = t.readUshort(
|
|
967
|
+
return A += 18, r.unitsPerEm = t.readUshort(a, A), A += 2, A += 16, r.xMin = t.readShort(a, A), A += 2, r.yMin = t.readShort(a, A), A += 2, r.xMax = t.readShort(a, A), A += 2, r.yMax = t.readShort(a, A), A += 2, A += 6, r.indexToLocFormat = t.readShort(a, A), r;
|
|
967
968
|
}
|
|
968
969
|
};
|
|
969
970
|
Q.T.hhea = {
|
|
970
|
-
parseTab: function(
|
|
971
|
+
parseTab: function(a, A, e) {
|
|
971
972
|
var t = Q.B, r = {};
|
|
972
973
|
A += 4;
|
|
973
974
|
for (var i = [
|
|
@@ -988,75 +989,75 @@ Q.T.hhea = {
|
|
|
988
989
|
"metricDataFormat",
|
|
989
990
|
"numberOfHMetrics"
|
|
990
991
|
], s = 0; s < i.length; s++) {
|
|
991
|
-
var
|
|
992
|
-
r[
|
|
992
|
+
var n = i[s], g = n == "advanceWidthMax" || n == "numberOfHMetrics" ? t.readUshort : t.readShort;
|
|
993
|
+
r[n] = g(a, A + s * 2);
|
|
993
994
|
}
|
|
994
995
|
return r;
|
|
995
996
|
}
|
|
996
997
|
};
|
|
997
998
|
Q.T.hmtx = {
|
|
998
|
-
parseTab: function(
|
|
999
|
-
for (var r = Q.B, i = [], s = [],
|
|
1000
|
-
B = r.readUshort(
|
|
1001
|
-
for (;
|
|
1002
|
-
i.push(B), s.push(
|
|
999
|
+
parseTab: function(a, A, e, t) {
|
|
1000
|
+
for (var r = Q.B, i = [], s = [], n = t.maxp.numGlyphs, g = t.hhea.numberOfHMetrics, B = 0, h = 0, E = 0; E < g; )
|
|
1001
|
+
B = r.readUshort(a, A + (E << 2)), h = r.readShort(a, A + (E << 2) + 2), i.push(B), s.push(h), E++;
|
|
1002
|
+
for (; E < n; )
|
|
1003
|
+
i.push(B), s.push(h), E++;
|
|
1003
1004
|
return { aWidth: i, lsBearing: s };
|
|
1004
1005
|
}
|
|
1005
1006
|
};
|
|
1006
1007
|
Q.T.maxp = {
|
|
1007
|
-
parseTab: function(
|
|
1008
|
+
parseTab: function(a, A, e) {
|
|
1008
1009
|
var t = Q.B, r = t.readUshort, i = {};
|
|
1009
|
-
return t.readUint(
|
|
1010
|
+
return t.readUint(a, A), A += 4, i.numGlyphs = r(a, A), A += 2, i;
|
|
1010
1011
|
}
|
|
1011
1012
|
};
|
|
1012
1013
|
Q.T.loca = {
|
|
1013
|
-
parseTab: function(
|
|
1014
|
-
var r = Q.B, i = [], s = t.head.indexToLocFormat,
|
|
1015
|
-
if (s == 0) for (var g = 0; g <
|
|
1016
|
-
if (s == 1) for (var g = 0; g <
|
|
1014
|
+
parseTab: function(a, A, e, t) {
|
|
1015
|
+
var r = Q.B, i = [], s = t.head.indexToLocFormat, n = t.maxp.numGlyphs + 1;
|
|
1016
|
+
if (s == 0) for (var g = 0; g < n; g++) i.push(r.readUshort(a, A + (g << 1)) << 1);
|
|
1017
|
+
if (s == 1) for (var g = 0; g < n; g++) i.push(r.readUint(a, A + (g << 2)));
|
|
1017
1018
|
return i;
|
|
1018
1019
|
}
|
|
1019
1020
|
};
|
|
1020
1021
|
Q.T.glyf = {
|
|
1021
|
-
parseTab: function(
|
|
1022
|
+
parseTab: function(a, A, e, t) {
|
|
1022
1023
|
for (var r = [], i = t.maxp.numGlyphs, s = 0; s < i; s++) r.push(null);
|
|
1023
1024
|
return r;
|
|
1024
1025
|
},
|
|
1025
|
-
_parseGlyf: function(
|
|
1026
|
-
var e = Q.B, t =
|
|
1026
|
+
_parseGlyf: function(a, A) {
|
|
1027
|
+
var e = Q.B, t = a._data, r = a.loca;
|
|
1027
1028
|
if (r[A] == r[A + 1]) return null;
|
|
1028
|
-
var i = Q.findTable(t, "glyf",
|
|
1029
|
+
var i = Q.findTable(t, "glyf", a._offset)[0] + r[A], s = {};
|
|
1029
1030
|
if (s.noc = e.readShort(t, i), i += 2, s.xMin = e.readShort(t, i), i += 2, s.yMin = e.readShort(t, i), i += 2, s.xMax = e.readShort(t, i), i += 2, s.yMax = e.readShort(t, i), i += 2, s.xMin >= s.xMax || s.yMin >= s.yMax) return null;
|
|
1030
1031
|
if (s.noc > 0) {
|
|
1031
1032
|
s.endPts = [];
|
|
1032
|
-
for (var
|
|
1033
|
+
for (var n = 0; n < s.noc; n++)
|
|
1033
1034
|
s.endPts.push(e.readUshort(t, i)), i += 2;
|
|
1034
1035
|
var g = e.readUshort(t, i);
|
|
1035
1036
|
if (i += 2, t.length - i < g) return null;
|
|
1036
1037
|
i += g;
|
|
1037
1038
|
var B = s.endPts[s.noc - 1] + 1;
|
|
1038
1039
|
s.flags = [];
|
|
1039
|
-
for (var
|
|
1040
|
-
var
|
|
1041
|
-
if (i++, s.flags.push(
|
|
1042
|
-
var
|
|
1040
|
+
for (var n = 0; n < B; n++) {
|
|
1041
|
+
var h = t[i];
|
|
1042
|
+
if (i++, s.flags.push(h), h & 8) {
|
|
1043
|
+
var E = t[i];
|
|
1043
1044
|
i++;
|
|
1044
|
-
for (var
|
|
1045
|
-
s.flags.push(
|
|
1045
|
+
for (var l = 0; l < E; l++)
|
|
1046
|
+
s.flags.push(h), n++;
|
|
1046
1047
|
}
|
|
1047
1048
|
}
|
|
1048
1049
|
s.xs = [];
|
|
1049
|
-
for (var
|
|
1050
|
-
var c = (s.flags[
|
|
1050
|
+
for (var n = 0; n < B; n++) {
|
|
1051
|
+
var c = (s.flags[n] & 2) != 0, d = (s.flags[n] & 16) != 0;
|
|
1051
1052
|
c ? (s.xs.push(d ? t[i] : -t[i]), i++) : d ? s.xs.push(0) : (s.xs.push(e.readShort(t, i)), i += 2);
|
|
1052
1053
|
}
|
|
1053
1054
|
s.ys = [];
|
|
1054
|
-
for (var
|
|
1055
|
-
var c = (s.flags[
|
|
1055
|
+
for (var n = 0; n < B; n++) {
|
|
1056
|
+
var c = (s.flags[n] & 4) != 0, d = (s.flags[n] & 32) != 0;
|
|
1056
1057
|
c ? (s.ys.push(d ? t[i] : -t[i]), i++) : d ? s.ys.push(0) : (s.ys.push(e.readShort(t, i)), i += 2);
|
|
1057
1058
|
}
|
|
1058
|
-
for (var u = 0, m = 0,
|
|
1059
|
-
u += s.xs[
|
|
1059
|
+
for (var u = 0, m = 0, n = 0; n < B; n++)
|
|
1060
|
+
u += s.xs[n], m += s.ys[n], s.xs[n] = u, s.ys[n] = m;
|
|
1060
1061
|
} else
|
|
1061
1062
|
s.parts = [];
|
|
1062
1063
|
return s;
|
|
@@ -1116,9 +1117,9 @@ class cA {
|
|
|
1116
1117
|
return e;
|
|
1117
1118
|
for (let t = 0; t < A.groups.length; t += 3) {
|
|
1118
1119
|
const r = A.groups[t], i = A.groups[t + 1], s = A.groups[t + 2];
|
|
1119
|
-
for (let
|
|
1120
|
-
if (s + (
|
|
1121
|
-
const B = String.fromCodePoint(
|
|
1120
|
+
for (let n = r; n <= i; n++)
|
|
1121
|
+
if (s + (n - r) > 0) {
|
|
1122
|
+
const B = String.fromCodePoint(n);
|
|
1122
1123
|
e.push(B);
|
|
1123
1124
|
}
|
|
1124
1125
|
}
|
|
@@ -1168,9 +1169,9 @@ class uA {
|
|
|
1168
1169
|
* @param renderer The WebGL renderer instance
|
|
1169
1170
|
*/
|
|
1170
1171
|
constructor(A) {
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1172
|
+
o(this, "_textureCanvas");
|
|
1173
|
+
o(this, "_textureContext");
|
|
1174
|
+
o(this, "_renderer");
|
|
1174
1175
|
this._renderer = A, this._textureCanvas = document.createElement("canvas"), this._textureContext = this._textureCanvas.getContext("2d", { willReadFrequently: !0, alpha: !1 });
|
|
1175
1176
|
}
|
|
1176
1177
|
/**
|
|
@@ -1182,13 +1183,13 @@ class uA {
|
|
|
1182
1183
|
* @returns Object containing framebuffer, columns, and rows
|
|
1183
1184
|
*/
|
|
1184
1185
|
createTextureAtlas(A, e, t, r) {
|
|
1185
|
-
const i = A.length, s = Math.ceil(Math.sqrt(i)),
|
|
1186
|
+
const i = A.length, s = Math.ceil(Math.sqrt(i)), n = Math.ceil(i / s), g = e.width * s, B = e.height * n;
|
|
1186
1187
|
this._setupCanvas(g, B, t, r), this._renderCharactersToCanvas(A, e, s, t), this._applyBlackWhiteThreshold();
|
|
1187
|
-
const
|
|
1188
|
-
return
|
|
1189
|
-
framebuffer:
|
|
1188
|
+
const h = this._renderer.createFramebuffer(g, B, { filter: "nearest" });
|
|
1189
|
+
return h.update(this._textureCanvas), {
|
|
1190
|
+
framebuffer: h,
|
|
1190
1191
|
columns: s,
|
|
1191
|
-
rows:
|
|
1192
|
+
rows: n
|
|
1192
1193
|
};
|
|
1193
1194
|
}
|
|
1194
1195
|
/**
|
|
@@ -1212,8 +1213,8 @@ class uA {
|
|
|
1212
1213
|
*/
|
|
1213
1214
|
_renderCharactersToCanvas(A, e, t, r) {
|
|
1214
1215
|
for (let i = 0; i < A.length; i++) {
|
|
1215
|
-
const s = i % t,
|
|
1216
|
-
this._textureContext.fillText(A[i].character,
|
|
1216
|
+
const s = i % t, n = Math.floor(i / t), g = s * e.width + e.width * 0.5, B = n * e.height + e.height * 0.5, h = Math.round(g - e.width * 0.5), E = Math.round(B - r * 0.5);
|
|
1217
|
+
this._textureContext.fillText(A[i].character, h, E);
|
|
1217
1218
|
}
|
|
1218
1219
|
}
|
|
1219
1220
|
/**
|
|
@@ -1225,8 +1226,8 @@ class uA {
|
|
|
1225
1226
|
_applyBlackWhiteThreshold(A = 128) {
|
|
1226
1227
|
const e = this._textureContext.getImageData(0, 0, this._textureCanvas.width, this._textureCanvas.height), t = e.data;
|
|
1227
1228
|
for (let r = 0; r < t.length; r += 4) {
|
|
1228
|
-
const i = 0.299 * t[r] + 0.587 * t[r + 1] + 0.114 * t[r + 2], s = A + 32,
|
|
1229
|
-
t[r] =
|
|
1229
|
+
const i = 0.299 * t[r] + 0.587 * t[r + 1] + 0.114 * t[r + 2], s = A + 32, n = i > s ? 255 : 0;
|
|
1230
|
+
t[r] = n, t[r + 1] = n, t[r + 2] = n;
|
|
1230
1231
|
}
|
|
1231
1232
|
this._textureContext.putImageData(e, 0, 0);
|
|
1232
1233
|
}
|
|
@@ -1236,8 +1237,8 @@ class dA {
|
|
|
1236
1237
|
* Creates a new MetricsCalculation instance.
|
|
1237
1238
|
*/
|
|
1238
1239
|
constructor() {
|
|
1239
|
-
|
|
1240
|
-
|
|
1240
|
+
o(this, "_tempCanvas");
|
|
1241
|
+
o(this, "_tempContext");
|
|
1241
1242
|
this._tempCanvas = document.createElement("canvas"), this._tempContext = this._tempCanvas.getContext("2d");
|
|
1242
1243
|
}
|
|
1243
1244
|
/**
|
|
@@ -1252,7 +1253,7 @@ class dA {
|
|
|
1252
1253
|
this._tempContext.font = `${e}px ${t}`;
|
|
1253
1254
|
let r = 0, i = 0;
|
|
1254
1255
|
for (const s of A) {
|
|
1255
|
-
const
|
|
1256
|
+
const n = this._tempContext.measureText(s), g = n.width, B = n.actualBoundingBoxAscent + n.actualBoundingBoxDescent;
|
|
1256
1257
|
g > 0 && (r = Math.max(r, g), i = Math.max(i, B));
|
|
1257
1258
|
}
|
|
1258
1259
|
return {
|
|
@@ -1271,16 +1272,16 @@ class fA {
|
|
|
1271
1272
|
createCharacterObjects(A, e) {
|
|
1272
1273
|
return A.map((t, r) => {
|
|
1273
1274
|
const i = t.codePointAt(0) || 0, s = this._generateCharacterColor(r);
|
|
1274
|
-
let
|
|
1275
|
+
let n = 0;
|
|
1275
1276
|
if (e.hmtx && e.hmtx.aWidth) {
|
|
1276
1277
|
const g = this._getGlyphIndex(e, i);
|
|
1277
|
-
g > 0 && e.hmtx.aWidth[g] !== void 0 && (
|
|
1278
|
+
g > 0 && e.hmtx.aWidth[g] !== void 0 && (n = e.hmtx.aWidth[g]);
|
|
1278
1279
|
}
|
|
1279
1280
|
return {
|
|
1280
1281
|
character: t,
|
|
1281
1282
|
unicode: i,
|
|
1282
1283
|
color: s,
|
|
1283
|
-
advanceWidth:
|
|
1284
|
+
advanceWidth: n
|
|
1284
1285
|
};
|
|
1285
1286
|
});
|
|
1286
1287
|
}
|
|
@@ -1303,9 +1304,9 @@ class fA {
|
|
|
1303
1304
|
{
|
|
1304
1305
|
const s = r.idRangeOffset[i] / 2 + (e - r.startCount[i]) - (r.startCount.length - i);
|
|
1305
1306
|
if (s >= 0 && s < r.glyphIdArray.length) {
|
|
1306
|
-
const
|
|
1307
|
-
if (
|
|
1308
|
-
return
|
|
1307
|
+
const n = r.glyphIdArray[s];
|
|
1308
|
+
if (n !== 0)
|
|
1309
|
+
return n + r.idDelta[i] & 65535;
|
|
1309
1310
|
}
|
|
1310
1311
|
}
|
|
1311
1312
|
}
|
|
@@ -1359,20 +1360,20 @@ class CA {
|
|
|
1359
1360
|
* @ignore
|
|
1360
1361
|
*/
|
|
1361
1362
|
constructor(A, e = 16) {
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1363
|
+
o(this, "_font");
|
|
1364
|
+
o(this, "_characters", []);
|
|
1365
|
+
o(this, "_fontFramebuffer");
|
|
1366
|
+
o(this, "_fontSize", 16);
|
|
1367
|
+
o(this, "_textureColumns", 0);
|
|
1368
|
+
o(this, "_textureRows", 0);
|
|
1369
|
+
o(this, "_maxGlyphDimensions", { width: 0, height: 0 });
|
|
1370
|
+
o(this, "_fontFace");
|
|
1371
|
+
o(this, "_fontFamilyName", "UrsaFont");
|
|
1371
1372
|
// Component classes
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1373
|
+
o(this, "_characterExtractor");
|
|
1374
|
+
o(this, "_textureAtlas");
|
|
1375
|
+
o(this, "_metricsCalculator");
|
|
1376
|
+
o(this, "_characterColorMapper");
|
|
1376
1377
|
this._fontSize = e, this._characterExtractor = new cA(), this._textureAtlas = new uA(A), this._metricsCalculator = new dA(), this._characterColorMapper = new fA();
|
|
1377
1378
|
}
|
|
1378
1379
|
/**
|
|
@@ -1386,7 +1387,7 @@ class CA {
|
|
|
1386
1387
|
if (A) {
|
|
1387
1388
|
const t = await fetch(A);
|
|
1388
1389
|
if (!t.ok)
|
|
1389
|
-
throw new
|
|
1390
|
+
throw new p(`Failed to load font file: ${t.status} ${t.statusText}`);
|
|
1390
1391
|
e = await t.arrayBuffer();
|
|
1391
1392
|
} else
|
|
1392
1393
|
e = await (await fetch(QA)).arrayBuffer();
|
|
@@ -1422,7 +1423,7 @@ class CA {
|
|
|
1422
1423
|
try {
|
|
1423
1424
|
const e = await fetch(A);
|
|
1424
1425
|
if (!e.ok)
|
|
1425
|
-
throw new
|
|
1426
|
+
throw new p(`Failed to load font file: ${e.status} ${e.statusText}`);
|
|
1426
1427
|
const t = await e.arrayBuffer();
|
|
1427
1428
|
await this._loadFontFace(t);
|
|
1428
1429
|
const r = Q.parse(t);
|
|
@@ -1430,7 +1431,7 @@ class CA {
|
|
|
1430
1431
|
throw new Error("Failed to parse font file");
|
|
1431
1432
|
this._font = r[0], await this._initializeFont();
|
|
1432
1433
|
} catch (e) {
|
|
1433
|
-
throw new
|
|
1434
|
+
throw new p(`Failed to load font: ${e instanceof Error ? e.message : "Unknown error"}`, e);
|
|
1434
1435
|
}
|
|
1435
1436
|
}
|
|
1436
1437
|
/**
|
|
@@ -1537,25 +1538,25 @@ class mA {
|
|
|
1537
1538
|
*/
|
|
1538
1539
|
constructor(A, e, t) {
|
|
1539
1540
|
/** The number of columns in the grid. */
|
|
1540
|
-
|
|
1541
|
+
o(this, "_cols");
|
|
1541
1542
|
/** The number of rows in the grid. */
|
|
1542
|
-
|
|
1543
|
+
o(this, "_rows");
|
|
1543
1544
|
/** The total width of the grid in pixels. */
|
|
1544
|
-
|
|
1545
|
+
o(this, "_width");
|
|
1545
1546
|
/** The total height of the grid in pixels. */
|
|
1546
|
-
|
|
1547
|
+
o(this, "_height");
|
|
1547
1548
|
/** The offset to the outer canvas on the x-axis when centering the grid. */
|
|
1548
|
-
|
|
1549
|
+
o(this, "_offsetX");
|
|
1549
1550
|
/** The offset to the outer canvas on the y-axis when centering the grid. */
|
|
1550
|
-
|
|
1551
|
+
o(this, "_offsetY");
|
|
1551
1552
|
/** Whether the grid dimensions are fixed, or responsive based on the canvas dimensions. */
|
|
1552
|
-
|
|
1553
|
+
o(this, "_fixedDimensions", !1);
|
|
1553
1554
|
/** The canvas element used to determine the grid dimensions. */
|
|
1554
|
-
|
|
1555
|
+
o(this, "_canvas");
|
|
1555
1556
|
/** The width of each cell in the grid. */
|
|
1556
|
-
|
|
1557
|
+
o(this, "_cellWidth");
|
|
1557
1558
|
/** The height of each cell in the grid. */
|
|
1558
|
-
|
|
1559
|
+
o(this, "_cellHeight");
|
|
1559
1560
|
this._canvas = A, this._cellWidth = e, this._cellHeight = t, this.reset();
|
|
1560
1561
|
}
|
|
1561
1562
|
/**
|
|
@@ -1666,10 +1667,12 @@ class mA {
|
|
|
1666
1667
|
}
|
|
1667
1668
|
class DA {
|
|
1668
1669
|
constructor(A, e = !1, t = {}) {
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
this
|
|
1670
|
+
o(this, "_canvas");
|
|
1671
|
+
o(this, "captureSource");
|
|
1672
|
+
o(this, "_isStandalone");
|
|
1673
|
+
o(this, "resizeObserver");
|
|
1674
|
+
o(this, "onTransformChange");
|
|
1675
|
+
this.captureSource = A, this._isStandalone = e, this._canvas = this.createCanvas(t.width, t.height), e && this.setupTransformObserver();
|
|
1673
1676
|
}
|
|
1674
1677
|
createCanvas(A, e) {
|
|
1675
1678
|
var r;
|
|
@@ -1678,12 +1681,12 @@ class DA {
|
|
|
1678
1681
|
t.width = A || 800, t.height = e || 600, document.body.appendChild(t);
|
|
1679
1682
|
else {
|
|
1680
1683
|
const i = this.captureSource.getBoundingClientRect();
|
|
1681
|
-
let s = Math.round(i.width),
|
|
1684
|
+
let s = Math.round(i.width), n = Math.round(i.height);
|
|
1682
1685
|
if (this.captureSource instanceof HTMLVideoElement) {
|
|
1683
|
-
const
|
|
1684
|
-
(s === 0 ||
|
|
1686
|
+
const h = this.captureSource;
|
|
1687
|
+
(s === 0 || n === 0) && h.videoWidth > 0 && h.videoHeight > 0 && (s = h.videoWidth, n = h.videoHeight);
|
|
1685
1688
|
}
|
|
1686
|
-
t.width = s, t.height =
|
|
1689
|
+
t.width = s, t.height = n, t.style.position = "absolute", t.style.pointerEvents = "none";
|
|
1687
1690
|
const g = window.getComputedStyle(this.captureSource);
|
|
1688
1691
|
let B = parseInt(g.zIndex || "0", 10);
|
|
1689
1692
|
isNaN(B) && (B = 0), t.style.zIndex = (B + 1).toString(), this.positionOverlayCanvas(t), (r = this.captureSource.parentNode) == null || r.insertBefore(t, this.captureSource.nextSibling);
|
|
@@ -1726,15 +1729,48 @@ class DA {
|
|
|
1726
1729
|
powerPreference: "high-performance"
|
|
1727
1730
|
}, e = this._canvas.getContext("webgl2", A) || this._canvas.getContext("webgl", A);
|
|
1728
1731
|
if (!e)
|
|
1729
|
-
throw new
|
|
1732
|
+
throw new p("WebGL context could not be created. Ensure your browser supports WebGL.");
|
|
1730
1733
|
return e;
|
|
1731
1734
|
}
|
|
1735
|
+
/**
|
|
1736
|
+
* Get the effective rendering dimensions accounting for CSS transforms
|
|
1737
|
+
*/
|
|
1738
|
+
getEffectiveRenderingDimensions() {
|
|
1739
|
+
if (!this._canvas)
|
|
1740
|
+
return { width: 0, height: 0 };
|
|
1741
|
+
const A = this._canvas.getBoundingClientRect(), e = Math.round(A.width), t = Math.round(A.height);
|
|
1742
|
+
if (this._isStandalone) {
|
|
1743
|
+
const r = this._canvas.width, i = this._canvas.height;
|
|
1744
|
+
if (e !== r || t !== i)
|
|
1745
|
+
return { width: e, height: t };
|
|
1746
|
+
}
|
|
1747
|
+
return { width: this._canvas.width, height: this._canvas.height };
|
|
1748
|
+
}
|
|
1749
|
+
/**
|
|
1750
|
+
* Check if the canvas is affected by CSS transforms
|
|
1751
|
+
*/
|
|
1752
|
+
isTransformed() {
|
|
1753
|
+
if (!this._canvas || !this._isStandalone) return !1;
|
|
1754
|
+
const A = this._canvas.getBoundingClientRect(), e = Math.round(A.width), t = Math.round(A.height);
|
|
1755
|
+
return e !== this._canvas.width || t !== this._canvas.height;
|
|
1756
|
+
}
|
|
1757
|
+
/**
|
|
1758
|
+
* Set up ResizeObserver to monitor for CSS transform changes
|
|
1759
|
+
*/
|
|
1760
|
+
setupTransformObserver() {
|
|
1761
|
+
typeof ResizeObserver > "u" || (this.resizeObserver = new ResizeObserver((A) => {
|
|
1762
|
+
for (const e of A) {
|
|
1763
|
+
const t = e.contentRect, r = Math.round(t.width), i = Math.round(t.height);
|
|
1764
|
+
this.onTransformChange && (r !== this._canvas.width || i !== this._canvas.height) && this.onTransformChange();
|
|
1765
|
+
}
|
|
1766
|
+
}), this.resizeObserver.observe(this._canvas));
|
|
1767
|
+
}
|
|
1732
1768
|
/**
|
|
1733
1769
|
* Dispose of this TextmodeCanvas and clean up all resources.
|
|
1734
1770
|
* This method is idempotent and safe to call multiple times.
|
|
1735
1771
|
*/
|
|
1736
1772
|
dispose() {
|
|
1737
|
-
if (this._canvas) {
|
|
1773
|
+
if (this.resizeObserver && (this.resizeObserver.disconnect(), this.resizeObserver = void 0), this._canvas) {
|
|
1738
1774
|
const A = this._canvas.getContext("webgl") || this._canvas.getContext("webgl2");
|
|
1739
1775
|
if (A) {
|
|
1740
1776
|
const e = A.getExtension("WEBGL_lose_context");
|
|
@@ -1764,15 +1800,15 @@ class x {
|
|
|
1764
1800
|
* @ignore
|
|
1765
1801
|
*/
|
|
1766
1802
|
constructor(A, e, t, r = {}) {
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1803
|
+
o(this, "renderer");
|
|
1804
|
+
o(this, "fontManager");
|
|
1805
|
+
o(this, "grid");
|
|
1806
|
+
o(this, "_characterFramebuffer");
|
|
1807
|
+
o(this, "_primaryColorFramebuffer");
|
|
1808
|
+
o(this, "_secondaryColorFramebuffer");
|
|
1809
|
+
o(this, "_rotationFramebuffer");
|
|
1810
|
+
o(this, "_transformFramebuffer");
|
|
1811
|
+
o(this, "_options");
|
|
1776
1812
|
this.renderer = A, this.fontManager = e, this.grid = t, this._options = r, 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);
|
|
1777
1813
|
}
|
|
1778
1814
|
/**
|
|
@@ -1833,7 +1869,7 @@ class x {
|
|
|
1833
1869
|
return this._options;
|
|
1834
1870
|
}
|
|
1835
1871
|
}
|
|
1836
|
-
class
|
|
1872
|
+
class pA {
|
|
1837
1873
|
/**
|
|
1838
1874
|
* Create a new color palette instance.
|
|
1839
1875
|
* @param renderer The renderer instance.
|
|
@@ -1841,9 +1877,9 @@ class PA {
|
|
|
1841
1877
|
*/
|
|
1842
1878
|
constructor(A, e) {
|
|
1843
1879
|
/** The framebuffer used to store the color palette. */
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1880
|
+
o(this, "_framebuffer");
|
|
1881
|
+
o(this, "_renderer");
|
|
1882
|
+
o(this, "_colors");
|
|
1847
1883
|
this._renderer = A, this._colors = e;
|
|
1848
1884
|
const t = Math.max(this._colors.length, 1);
|
|
1849
1885
|
this._framebuffer = this._renderer.createFramebuffer(t, 1), this._updateFramebuffer();
|
|
@@ -1891,8 +1927,8 @@ class PA {
|
|
|
1891
1927
|
class z extends x {
|
|
1892
1928
|
constructor(e, t, r, i = {}) {
|
|
1893
1929
|
super(e, t, r, i);
|
|
1894
|
-
|
|
1895
|
-
this.palette = new
|
|
1930
|
+
o(this, "palette");
|
|
1931
|
+
this.palette = new pA(this.renderer, this.fontManager.getCharacterColors(" .:-=+*%@#"));
|
|
1896
1932
|
}
|
|
1897
1933
|
/**
|
|
1898
1934
|
* Sets the characters used for mapping.
|
|
@@ -1914,10 +1950,10 @@ class z extends x {
|
|
|
1914
1950
|
* @param a Alpha component (0-255).
|
|
1915
1951
|
*/
|
|
1916
1952
|
characterColor(e, t, r, i = 255) {
|
|
1917
|
-
let s,
|
|
1953
|
+
let s, n, g, B;
|
|
1918
1954
|
if (typeof e == "string") {
|
|
1919
|
-
const
|
|
1920
|
-
if (!
|
|
1955
|
+
const h = this.parseHexColor(e);
|
|
1956
|
+
if (!h) {
|
|
1921
1957
|
f.validate(
|
|
1922
1958
|
!1,
|
|
1923
1959
|
"Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
|
|
@@ -1925,14 +1961,14 @@ class z extends x {
|
|
|
1925
1961
|
);
|
|
1926
1962
|
return;
|
|
1927
1963
|
}
|
|
1928
|
-
[s,
|
|
1929
|
-
} else if (s = e,
|
|
1930
|
-
[s,
|
|
1964
|
+
[s, n, g, B] = h;
|
|
1965
|
+
} else if (s = e, n = t !== void 0 ? t : e, g = r !== void 0 ? r : e, B = i, !f.validate(
|
|
1966
|
+
[s, n, g, B].every((h) => h >= 0 && h <= 255),
|
|
1931
1967
|
"Character color values must be between 0 and 255",
|
|
1932
|
-
{ method: "characterColor", providedValues: { r: s, g:
|
|
1968
|
+
{ method: "characterColor", providedValues: { r: s, g: n, b: g, a: B } }
|
|
1933
1969
|
))
|
|
1934
1970
|
return;
|
|
1935
|
-
this._options.characterColor = [s / 255,
|
|
1971
|
+
this._options.characterColor = [s / 255, n / 255, g / 255, B / 255];
|
|
1936
1972
|
}
|
|
1937
1973
|
/**
|
|
1938
1974
|
* Sets the character color mode.
|
|
@@ -1956,10 +1992,10 @@ class z extends x {
|
|
|
1956
1992
|
* @param a Alpha component (0-255).
|
|
1957
1993
|
*/
|
|
1958
1994
|
cellColor(e, t, r, i = 255) {
|
|
1959
|
-
let s,
|
|
1995
|
+
let s, n, g, B;
|
|
1960
1996
|
if (typeof e == "string") {
|
|
1961
|
-
const
|
|
1962
|
-
if (!
|
|
1997
|
+
const h = this.parseHexColor(e);
|
|
1998
|
+
if (!h) {
|
|
1963
1999
|
f.validate(
|
|
1964
2000
|
!1,
|
|
1965
2001
|
"Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
|
|
@@ -1967,14 +2003,14 @@ class z extends x {
|
|
|
1967
2003
|
);
|
|
1968
2004
|
return;
|
|
1969
2005
|
}
|
|
1970
|
-
[s,
|
|
1971
|
-
} else if (s = e,
|
|
1972
|
-
[s,
|
|
2006
|
+
[s, n, g, B] = h;
|
|
2007
|
+
} else if (s = e, n = t !== void 0 ? t : e, g = r !== void 0 ? r : e, B = i, !f.validate(
|
|
2008
|
+
[s, n, g, B].every((h) => h >= 0 && h <= 255),
|
|
1973
2009
|
"Cell color values must be between 0 and 255",
|
|
1974
|
-
{ method: "cellColor", providedValues: { r: s, g:
|
|
2010
|
+
{ method: "cellColor", providedValues: { r: s, g: n, b: g, a: B } }
|
|
1975
2011
|
))
|
|
1976
2012
|
return;
|
|
1977
|
-
this._options.cellColor = [s / 255,
|
|
2013
|
+
this._options.cellColor = [s / 255, n / 255, g / 255, B / 255];
|
|
1978
2014
|
}
|
|
1979
2015
|
/**
|
|
1980
2016
|
* Sets the cell color mode.
|
|
@@ -2050,8 +2086,8 @@ class z extends x {
|
|
|
2050
2086
|
return [t, r, i, 255];
|
|
2051
2087
|
}
|
|
2052
2088
|
}
|
|
2053
|
-
var
|
|
2054
|
-
const
|
|
2089
|
+
var PA = "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);}}", wA = "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);}}", _A = "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);}}", IA = "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);}}", vA = "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);}";
|
|
2090
|
+
const bA = {
|
|
2055
2091
|
/** Enable/disable the renderer */
|
|
2056
2092
|
enabled: !0,
|
|
2057
2093
|
/** Characters used for brightness mapping (from darkest to brightest) */
|
|
@@ -2077,7 +2113,7 @@ const vA = {
|
|
|
2077
2113
|
/** Range of brightness values to map to ASCII characters */
|
|
2078
2114
|
brightnessRange: [0, 255]
|
|
2079
2115
|
};
|
|
2080
|
-
class
|
|
2116
|
+
class k extends z {
|
|
2081
2117
|
/**
|
|
2082
2118
|
* Creates a new TextmodeBrightnessConverter instance.
|
|
2083
2119
|
* @param renderer Renderer instance for texture creation
|
|
@@ -2086,14 +2122,14 @@ class O extends z {
|
|
|
2086
2122
|
* @ignore
|
|
2087
2123
|
*/
|
|
2088
2124
|
constructor(e, t, r) {
|
|
2089
|
-
super(e, t, r, { ...
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
this.sampleShader = new
|
|
2125
|
+
super(e, t, r, { ...bA });
|
|
2126
|
+
o(this, "sampleShader");
|
|
2127
|
+
o(this, "colorFillShader");
|
|
2128
|
+
o(this, "charMappingShader");
|
|
2129
|
+
o(this, "transformFillShader");
|
|
2130
|
+
o(this, "rotationFillShader");
|
|
2131
|
+
o(this, "sampleFramebuffer");
|
|
2132
|
+
this.sampleShader = new w(e.context, _, PA), this.colorFillShader = new w(e.context, _, wA), this.transformFillShader = new w(e.context, _, _A), this.rotationFillShader = new w(e.context, _, IA), this.charMappingShader = new w(e.context, _, vA), this.sampleFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
|
|
2097
2133
|
}
|
|
2098
2134
|
convert(e) {
|
|
2099
2135
|
this.sampleFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.sampleShader), this.renderer.setUniform("u_sketchTexture", e), 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();
|
|
@@ -2118,7 +2154,7 @@ class O extends z {
|
|
|
2118
2154
|
}
|
|
2119
2155
|
const LA = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2120
2156
|
__proto__: null,
|
|
2121
|
-
TextmodeBrightnessConverter:
|
|
2157
|
+
TextmodeBrightnessConverter: k,
|
|
2122
2158
|
TextmodeConverter: x,
|
|
2123
2159
|
TextmodeFeatureConverter: z
|
|
2124
2160
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
@@ -2132,19 +2168,19 @@ class FA {
|
|
|
2132
2168
|
* @ignore
|
|
2133
2169
|
*/
|
|
2134
2170
|
constructor(A, e, t) {
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
this.renderer = A, this.font = e, this.grid = t, this._asciiShader = this.renderer.createShader(
|
|
2147
|
-
{ name: "brightness", converter: new
|
|
2171
|
+
o(this, "renderer");
|
|
2172
|
+
o(this, "font");
|
|
2173
|
+
o(this, "grid");
|
|
2174
|
+
o(this, "converters");
|
|
2175
|
+
o(this, "_resultFramebuffer");
|
|
2176
|
+
o(this, "_asciiShader");
|
|
2177
|
+
o(this, "_characterFramebuffer");
|
|
2178
|
+
o(this, "_primaryColorFramebuffer");
|
|
2179
|
+
o(this, "_secondaryColorFramebuffer");
|
|
2180
|
+
o(this, "_rotationFramebuffer");
|
|
2181
|
+
o(this, "_transformFramebuffer");
|
|
2182
|
+
this.renderer = A, this.font = e, this.grid = t, this._asciiShader = this.renderer.createShader(_, xA), this.converters = [
|
|
2183
|
+
{ name: "brightness", converter: new k(A, e, t) },
|
|
2148
2184
|
{ name: "custom", converter: new x(A, e, t) }
|
|
2149
2185
|
], this._characterFramebuffer = this.renderer.createFramebuffer(t.cols, t.rows), this._primaryColorFramebuffer = this.renderer.createFramebuffer(t.cols, t.rows), this._secondaryColorFramebuffer = this.renderer.createFramebuffer(t.cols, t.rows), this._rotationFramebuffer = this.renderer.createFramebuffer(t.cols, t.rows), this._transformFramebuffer = this.renderer.createFramebuffer(t.cols, t.rows), this._resultFramebuffer = this.renderer.createFramebuffer(this.grid.width, this.grid.height);
|
|
2150
2186
|
}
|
|
@@ -2206,7 +2242,7 @@ class FA {
|
|
|
2206
2242
|
))
|
|
2207
2243
|
return;
|
|
2208
2244
|
let t;
|
|
2209
|
-
return e === "brightness" ? t = new
|
|
2245
|
+
return e === "brightness" ? t = new k(this.renderer, this.font, this.grid) : t = new x(this.renderer, this.font, this.grid), this.converters.push({ name: A, converter: t }), t;
|
|
2210
2246
|
}
|
|
2211
2247
|
/**
|
|
2212
2248
|
* Removes a converter from the pipeline by name or instance.
|
|
@@ -2309,13 +2345,13 @@ class L {
|
|
|
2309
2345
|
* @returns Object containing all pixel data arrays
|
|
2310
2346
|
*/
|
|
2311
2347
|
extractFramebufferData(A) {
|
|
2312
|
-
const e = A.get("brightness"), t = e == null ? void 0 : e.characterFramebuffer, r = e == null ? void 0 : e.primaryColorFramebuffer, i = e == null ? void 0 : e.secondaryColorFramebuffer, s = e == null ? void 0 : e.transformFramebuffer,
|
|
2313
|
-
return t == null || t.loadPixels(), r == null || r.loadPixels(), i == null || i.loadPixels(), s == null || s.loadPixels(),
|
|
2348
|
+
const e = A.get("brightness"), t = e == null ? void 0 : e.characterFramebuffer, r = e == null ? void 0 : e.primaryColorFramebuffer, i = e == null ? void 0 : e.secondaryColorFramebuffer, s = e == null ? void 0 : e.transformFramebuffer, n = e == null ? void 0 : e.rotationFramebuffer;
|
|
2349
|
+
return t == null || t.loadPixels(), r == null || r.loadPixels(), i == null || i.loadPixels(), s == null || s.loadPixels(), n == null || n.loadPixels(), {
|
|
2314
2350
|
characterPixels: (t == null ? void 0 : t.pixels) || new Uint8Array(0),
|
|
2315
2351
|
primaryColorPixels: (r == null ? void 0 : r.pixels) || new Uint8Array(0),
|
|
2316
2352
|
secondaryColorPixels: (i == null ? void 0 : i.pixels) || new Uint8Array(0),
|
|
2317
2353
|
transformPixels: (s == null ? void 0 : s.pixels) || new Uint8Array(0),
|
|
2318
|
-
rotationPixels: (
|
|
2354
|
+
rotationPixels: (n == null ? void 0 : n.pixels) || new Uint8Array(0)
|
|
2319
2355
|
};
|
|
2320
2356
|
}
|
|
2321
2357
|
/**
|
|
@@ -2410,9 +2446,9 @@ class yA extends L {
|
|
|
2410
2446
|
* @returns Transform data object
|
|
2411
2447
|
*/
|
|
2412
2448
|
extractTransformData(A, e, t) {
|
|
2413
|
-
const r = A[t], i = A[t + 1], s = A[t + 2],
|
|
2449
|
+
const r = A[t], i = A[t + 1], s = A[t + 2], n = r === 255, g = i === 255, B = s === 255, h = e[t], E = e[t + 1], l = h + E / 255, c = Math.round(l * 360 / 255 * 100) / 100;
|
|
2414
2450
|
return {
|
|
2415
|
-
isInverted:
|
|
2451
|
+
isInverted: n,
|
|
2416
2452
|
flipHorizontal: g,
|
|
2417
2453
|
flipVertical: B,
|
|
2418
2454
|
rotation: c
|
|
@@ -2445,27 +2481,27 @@ class yA extends L {
|
|
|
2445
2481
|
let r = 0;
|
|
2446
2482
|
for (let i = 0; i < e.rows; i++)
|
|
2447
2483
|
for (let s = 0; s < e.cols; s++) {
|
|
2448
|
-
const
|
|
2484
|
+
const n = r * 4, g = this.getCharacterIndex(
|
|
2449
2485
|
A.characterPixels,
|
|
2450
|
-
|
|
2486
|
+
n
|
|
2451
2487
|
);
|
|
2452
|
-
let B = this.pixelsToRGBA(A.primaryColorPixels,
|
|
2453
|
-
const
|
|
2488
|
+
let B = this.pixelsToRGBA(A.primaryColorPixels, n), h = this.pixelsToRGBA(A.secondaryColorPixels, n);
|
|
2489
|
+
const E = this.extractTransformData(
|
|
2454
2490
|
A.transformPixels,
|
|
2455
2491
|
A.rotationPixels,
|
|
2456
|
-
|
|
2492
|
+
n
|
|
2457
2493
|
);
|
|
2458
|
-
if (
|
|
2494
|
+
if (E.isInverted) {
|
|
2459
2495
|
const c = B;
|
|
2460
|
-
B =
|
|
2496
|
+
B = h, h = c;
|
|
2461
2497
|
}
|
|
2462
|
-
const
|
|
2498
|
+
const l = this.calculateCellPosition(s, i, e);
|
|
2463
2499
|
t.push({
|
|
2464
2500
|
charIndex: g,
|
|
2465
2501
|
primaryColor: B,
|
|
2466
|
-
secondaryColor:
|
|
2467
|
-
transform:
|
|
2468
|
-
position:
|
|
2502
|
+
secondaryColor: h,
|
|
2503
|
+
transform: E,
|
|
2504
|
+
position: l
|
|
2469
2505
|
}), r++;
|
|
2470
2506
|
}
|
|
2471
2507
|
return t;
|
|
@@ -2490,9 +2526,9 @@ class TA {
|
|
|
2490
2526
|
{
|
|
2491
2527
|
const s = r.idRangeOffset[i] / 2 + (e - r.startCount[i]) - (r.startCount.length - i);
|
|
2492
2528
|
if (s >= 0 && s < r.glyphIdArray.length) {
|
|
2493
|
-
const
|
|
2494
|
-
if (
|
|
2495
|
-
return
|
|
2529
|
+
const n = r.glyphIdArray[s];
|
|
2530
|
+
if (n !== 0)
|
|
2531
|
+
return n + r.idDelta[i] & 65535;
|
|
2496
2532
|
}
|
|
2497
2533
|
}
|
|
2498
2534
|
}
|
|
@@ -2542,34 +2578,34 @@ class TA {
|
|
|
2542
2578
|
*/
|
|
2543
2579
|
glyphToSVGPath(A, e, t, r) {
|
|
2544
2580
|
if (!A || !A.xs) return "";
|
|
2545
|
-
const { xs: i, ys: s, endPts:
|
|
2546
|
-
if (!i || !s || !
|
|
2547
|
-
let B = "",
|
|
2548
|
-
for (let
|
|
2549
|
-
const
|
|
2550
|
-
if (!(
|
|
2551
|
-
if (
|
|
2552
|
-
const c = e + i[
|
|
2581
|
+
const { xs: i, ys: s, endPts: n, flags: g } = A;
|
|
2582
|
+
if (!i || !s || !n || !g) return "";
|
|
2583
|
+
let B = "", h = 0;
|
|
2584
|
+
for (let E = 0; E < n.length; E++) {
|
|
2585
|
+
const l = n[E];
|
|
2586
|
+
if (!(l < h)) {
|
|
2587
|
+
if (l >= h) {
|
|
2588
|
+
const c = e + i[h] * r, d = t - s[h] * r;
|
|
2553
2589
|
B += `M${c.toFixed(2)},${d.toFixed(2)}`;
|
|
2554
|
-
let u =
|
|
2555
|
-
for (; u <=
|
|
2590
|
+
let u = h + 1;
|
|
2591
|
+
for (; u <= l; )
|
|
2556
2592
|
if ((g[u] & 1) !== 0) {
|
|
2557
2593
|
const D = e + i[u] * r, C = t - s[u] * r;
|
|
2558
2594
|
B += `L${D.toFixed(2)},${C.toFixed(2)}`, u++;
|
|
2559
2595
|
} else {
|
|
2560
2596
|
const D = e + i[u] * r, C = t - s[u] * r;
|
|
2561
|
-
let
|
|
2562
|
-
if ((g[
|
|
2563
|
-
const
|
|
2564
|
-
B += `Q${D.toFixed(2)},${C.toFixed(2)} ${
|
|
2597
|
+
let P = u + 1 > l ? h : u + 1;
|
|
2598
|
+
if ((g[P] & 1) !== 0) {
|
|
2599
|
+
const v = e + i[P] * r, I = t - s[P] * r;
|
|
2600
|
+
B += `Q${D.toFixed(2)},${C.toFixed(2)} ${v.toFixed(2)},${I.toFixed(2)}`, u = P + 1;
|
|
2565
2601
|
} else {
|
|
2566
|
-
const
|
|
2567
|
-
B += `Q${D.toFixed(2)},${C.toFixed(2)} ${R.toFixed(2)},${T.toFixed(2)}`, u =
|
|
2602
|
+
const v = e + i[P] * r, I = t - s[P] * r, R = (D + v) / 2, T = (C + I) / 2;
|
|
2603
|
+
B += `Q${D.toFixed(2)},${C.toFixed(2)} ${R.toFixed(2)},${T.toFixed(2)}`, u = P;
|
|
2568
2604
|
}
|
|
2569
2605
|
}
|
|
2570
2606
|
B += "Z";
|
|
2571
2607
|
}
|
|
2572
|
-
|
|
2608
|
+
h = l + 1;
|
|
2573
2609
|
}
|
|
2574
2610
|
}
|
|
2575
2611
|
return B;
|
|
@@ -2585,14 +2621,14 @@ class TA {
|
|
|
2585
2621
|
*/
|
|
2586
2622
|
generateCharacterPath(A, e, t, r, i) {
|
|
2587
2623
|
try {
|
|
2588
|
-
const s = A.codePointAt(0) || 0,
|
|
2589
|
-
if (
|
|
2624
|
+
const s = A.codePointAt(0) || 0, n = this.getGlyphIndex(e, s);
|
|
2625
|
+
if (n === 0)
|
|
2590
2626
|
return this.createEmptyPath();
|
|
2591
2627
|
let g = null;
|
|
2592
2628
|
try {
|
|
2593
|
-
e.glyf && e.glyf[
|
|
2629
|
+
e.glyf && e.glyf[n] !== null ? g = e.glyf[n] : Q && Q.T && Q.T.glyf && Q.T.glyf._parseGlyf && (g = Q.T.glyf._parseGlyf(e, n), e.glyf && g && (e.glyf[n] = g));
|
|
2594
2630
|
} catch (B) {
|
|
2595
|
-
console.warn(`Failed to parse glyph ${
|
|
2631
|
+
console.warn(`Failed to parse glyph ${n}:`, B);
|
|
2596
2632
|
}
|
|
2597
2633
|
return g ? this.createGlyphPath(e, g, t, r, i) : this.createEmptyPath();
|
|
2598
2634
|
} catch (s) {
|
|
@@ -2611,10 +2647,10 @@ class TA {
|
|
|
2611
2647
|
* @param advanceWidth Character advance width
|
|
2612
2648
|
* @returns SVG path data string or null if generation fails
|
|
2613
2649
|
*/
|
|
2614
|
-
generatePositionedCharacterPath(A, e, t, r, i, s,
|
|
2650
|
+
generatePositionedCharacterPath(A, e, t, r, i, s, n, g) {
|
|
2615
2651
|
try {
|
|
2616
|
-
const B =
|
|
2617
|
-
return this.generateCharacterPath(A, e,
|
|
2652
|
+
const B = n / e.head.unitsPerEm, h = g * B, E = t + (i - h) / 2, l = r + (s + n * 0.7) / 2;
|
|
2653
|
+
return this.generateCharacterPath(A, e, E, l, n).toSVG() || null;
|
|
2618
2654
|
} catch (B) {
|
|
2619
2655
|
return console.warn(`Failed to generate positioned character path for "${A}":`, B), null;
|
|
2620
2656
|
}
|
|
@@ -2622,7 +2658,7 @@ class TA {
|
|
|
2622
2658
|
}
|
|
2623
2659
|
class SA {
|
|
2624
2660
|
constructor() {
|
|
2625
|
-
|
|
2661
|
+
o(this, "pathGenerator");
|
|
2626
2662
|
this.pathGenerator = new TA();
|
|
2627
2663
|
}
|
|
2628
2664
|
/**
|
|
@@ -2675,12 +2711,12 @@ class SA {
|
|
|
2675
2711
|
* @returns Transform attribute string or empty string
|
|
2676
2712
|
*/
|
|
2677
2713
|
generateTransformAttribute(A, e) {
|
|
2678
|
-
const { transform: t, position: r } = A, i = r.cellX + e.cellWidth / 2, s = r.cellY + e.cellHeight / 2,
|
|
2714
|
+
const { transform: t, position: r } = A, i = r.cellX + e.cellWidth / 2, s = r.cellY + e.cellHeight / 2, n = [];
|
|
2679
2715
|
if (t.flipHorizontal || t.flipVertical) {
|
|
2680
2716
|
const g = t.flipHorizontal ? -1 : 1, B = t.flipVertical ? -1 : 1;
|
|
2681
|
-
|
|
2717
|
+
n.push(`translate(${i} ${s})`), n.push(`scale(${g} ${B})`), n.push(`translate(${-i} ${-s})`);
|
|
2682
2718
|
}
|
|
2683
|
-
return t.rotation &&
|
|
2719
|
+
return t.rotation && n.push(`rotate(${t.rotation} ${i} ${s})`), n.length ? ` transform="${n.join(" ")}"` : "";
|
|
2684
2720
|
}
|
|
2685
2721
|
/**
|
|
2686
2722
|
* Generates background rectangle for a cell
|
|
@@ -2721,10 +2757,10 @@ class SA {
|
|
|
2721
2757
|
);
|
|
2722
2758
|
if (!s)
|
|
2723
2759
|
return "";
|
|
2724
|
-
const
|
|
2760
|
+
const n = this.rgbaToColorString(A.primaryColor);
|
|
2725
2761
|
return r.drawMode === "stroke" ? `
|
|
2726
|
-
<path id="${`path-${A.charIndex}-${A.position.cellX}-${A.position.cellY}`.replace(/\./g, "-")}" d="${s}" stroke="${
|
|
2727
|
-
<path d="${s}" fill="${
|
|
2762
|
+
<path id="${`path-${A.charIndex}-${A.position.cellX}-${A.position.cellY}`.replace(/\./g, "-")}" d="${s}" stroke="${n}" stroke-width="${r.strokeWidth}" fill="none" />` : `
|
|
2763
|
+
<path d="${s}" fill="${n}" />`;
|
|
2728
2764
|
}
|
|
2729
2765
|
/**
|
|
2730
2766
|
* Generates complete SVG content for a single cell
|
|
@@ -2737,10 +2773,10 @@ class SA {
|
|
|
2737
2773
|
generateCellContent(A, e, t, r) {
|
|
2738
2774
|
let i = "";
|
|
2739
2775
|
i += this.generateCellBackground(A, e, r);
|
|
2740
|
-
const s = this.generateTransformAttribute(A, e),
|
|
2741
|
-
return
|
|
2742
|
-
<g${s}>`, i +=
|
|
2743
|
-
</g>`) : i +=
|
|
2776
|
+
const s = this.generateTransformAttribute(A, e), n = this.generateCharacterPath(A, e, t, r);
|
|
2777
|
+
return n && (s ? (i += `
|
|
2778
|
+
<g${s}>`, i += n, i += `
|
|
2779
|
+
</g>`) : i += n), i;
|
|
2744
2780
|
}
|
|
2745
2781
|
/**
|
|
2746
2782
|
* Generates the complete SVG content from cell data
|
|
@@ -2798,11 +2834,11 @@ class RA extends H {
|
|
|
2798
2834
|
this.downloadSVG(A, e || this.generateDefaultFilename());
|
|
2799
2835
|
}
|
|
2800
2836
|
}
|
|
2801
|
-
class
|
|
2837
|
+
class X {
|
|
2802
2838
|
constructor() {
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2839
|
+
o(this, "dataExtractor");
|
|
2840
|
+
o(this, "contentGenerator");
|
|
2841
|
+
o(this, "fileHandler");
|
|
2806
2842
|
this.dataExtractor = new yA(), this.contentGenerator = new SA(), this.fileHandler = new RA();
|
|
2807
2843
|
}
|
|
2808
2844
|
/**
|
|
@@ -2850,7 +2886,7 @@ class W {
|
|
|
2850
2886
|
}
|
|
2851
2887
|
}
|
|
2852
2888
|
}
|
|
2853
|
-
class
|
|
2889
|
+
class MA extends L {
|
|
2854
2890
|
/**
|
|
2855
2891
|
* Extracts character data for TXT generation
|
|
2856
2892
|
* @param framebufferData Framebuffer pixel data
|
|
@@ -2860,16 +2896,16 @@ class GA extends L {
|
|
|
2860
2896
|
* @returns 2D array of characters (rows x columns)
|
|
2861
2897
|
*/
|
|
2862
2898
|
extractCharacterGrid(A, e, t, r = " ") {
|
|
2863
|
-
var
|
|
2899
|
+
var n;
|
|
2864
2900
|
const i = [];
|
|
2865
2901
|
let s = 0;
|
|
2866
2902
|
for (let g = 0; g < e.rows; g++) {
|
|
2867
2903
|
const B = [];
|
|
2868
|
-
for (let
|
|
2869
|
-
const
|
|
2904
|
+
for (let h = 0; h < e.cols; h++) {
|
|
2905
|
+
const E = s * 4, l = this.getCharacterIndex(
|
|
2870
2906
|
A.characterPixels,
|
|
2871
|
-
|
|
2872
|
-
), c = ((
|
|
2907
|
+
E
|
|
2908
|
+
), c = ((n = t.characters[l]) == null ? void 0 : n.character) || r;
|
|
2873
2909
|
B.push(c), s++;
|
|
2874
2910
|
}
|
|
2875
2911
|
i.push(B);
|
|
@@ -2877,7 +2913,7 @@ class GA extends L {
|
|
|
2877
2913
|
return i;
|
|
2878
2914
|
}
|
|
2879
2915
|
}
|
|
2880
|
-
class
|
|
2916
|
+
class GA {
|
|
2881
2917
|
/**
|
|
2882
2918
|
* Generates TXT content from a 2D character array
|
|
2883
2919
|
* @param characterGrid 2D array of characters (rows x columns)
|
|
@@ -2922,10 +2958,10 @@ class UA extends H {
|
|
|
2922
2958
|
}
|
|
2923
2959
|
class $ {
|
|
2924
2960
|
constructor() {
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
this.dataExtractor = new
|
|
2961
|
+
o(this, "dataExtractor");
|
|
2962
|
+
o(this, "contentGenerator");
|
|
2963
|
+
o(this, "fileHandler");
|
|
2964
|
+
this.dataExtractor = new MA(), this.contentGenerator = new GA(), this.fileHandler = new UA();
|
|
2929
2965
|
}
|
|
2930
2966
|
/**
|
|
2931
2967
|
* Applies default values to TXT export options
|
|
@@ -2983,8 +3019,8 @@ class YA extends L {
|
|
|
2983
3019
|
const r = A.canvas;
|
|
2984
3020
|
if (e === 1 && t === "transparent")
|
|
2985
3021
|
return r;
|
|
2986
|
-
const i = document.createElement("canvas"), s = i.getContext("2d"),
|
|
2987
|
-
return i.width =
|
|
3022
|
+
const i = document.createElement("canvas"), s = i.getContext("2d"), n = Math.round(r.width * e), g = Math.round(r.height * e);
|
|
3023
|
+
return i.width = n, i.height = g, t !== "transparent" && (s.fillStyle = t, s.fillRect(0, 0, n, g)), s.imageSmoothingEnabled = !1, s.drawImage(
|
|
2988
3024
|
r,
|
|
2989
3025
|
0,
|
|
2990
3026
|
0,
|
|
@@ -2992,12 +3028,12 @@ class YA extends L {
|
|
|
2992
3028
|
r.height,
|
|
2993
3029
|
0,
|
|
2994
3030
|
0,
|
|
2995
|
-
|
|
3031
|
+
n,
|
|
2996
3032
|
g
|
|
2997
3033
|
), i;
|
|
2998
3034
|
}
|
|
2999
3035
|
}
|
|
3000
|
-
class
|
|
3036
|
+
class OA {
|
|
3001
3037
|
/**
|
|
3002
3038
|
* Generates image data from canvas
|
|
3003
3039
|
* @param canvas The canvas containing the image data
|
|
@@ -3016,8 +3052,8 @@ class kA {
|
|
|
3016
3052
|
*/
|
|
3017
3053
|
async generateImageBlob(A, e) {
|
|
3018
3054
|
return new Promise((t, r) => {
|
|
3019
|
-
const i = this.getMimeType(e.format), s = (
|
|
3020
|
-
|
|
3055
|
+
const i = this.getMimeType(e.format), s = (n) => {
|
|
3056
|
+
n ? t(n) : r(new Error(`Failed to generate ${e.format.toUpperCase()} blob`));
|
|
3021
3057
|
};
|
|
3022
3058
|
e.format === "png" ? A.toBlob(s, i) : A.toBlob(s, i, e.quality);
|
|
3023
3059
|
});
|
|
@@ -3044,7 +3080,7 @@ const J = {
|
|
|
3044
3080
|
png: "image/png",
|
|
3045
3081
|
jpg: "image/jpeg",
|
|
3046
3082
|
webp: "image/webp"
|
|
3047
|
-
},
|
|
3083
|
+
}, O = {
|
|
3048
3084
|
png: ".png",
|
|
3049
3085
|
jpg: ".jpg",
|
|
3050
3086
|
webp: ".webp"
|
|
@@ -3058,7 +3094,7 @@ class VA extends H {
|
|
|
3058
3094
|
*/
|
|
3059
3095
|
saveImage(A, e, t) {
|
|
3060
3096
|
try {
|
|
3061
|
-
const r =
|
|
3097
|
+
const r = O[t];
|
|
3062
3098
|
typeof A == "string" ? this.saveImageFromDataURL(A, this.sanitizeFilename(e) + r) : this.saveImageFromBlob(A, this.sanitizeFilename(e) + r);
|
|
3063
3099
|
} catch (r) {
|
|
3064
3100
|
throw console.error(`Failed to save ${t.toUpperCase()} image:`, r), new Error(`Image save failed: ${r instanceof Error ? r.message : "Unknown error"}`);
|
|
@@ -3093,7 +3129,7 @@ class VA extends H {
|
|
|
3093
3129
|
* @returns True if the format is supported for saving
|
|
3094
3130
|
*/
|
|
3095
3131
|
validateSaveSupport(A) {
|
|
3096
|
-
return A in J && A in
|
|
3132
|
+
return A in J && A in O;
|
|
3097
3133
|
}
|
|
3098
3134
|
/**
|
|
3099
3135
|
* Gets the MIME type for the specified image format
|
|
@@ -3109,15 +3145,15 @@ class VA extends H {
|
|
|
3109
3145
|
* @returns The file extension (including the dot)
|
|
3110
3146
|
*/
|
|
3111
3147
|
getFileExtension(A) {
|
|
3112
|
-
return
|
|
3148
|
+
return O[A];
|
|
3113
3149
|
}
|
|
3114
3150
|
}
|
|
3115
|
-
class
|
|
3151
|
+
class kA {
|
|
3116
3152
|
constructor() {
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
this.dataExtractor = new YA(), this.contentGenerator = new
|
|
3153
|
+
o(this, "dataExtractor");
|
|
3154
|
+
o(this, "contentGenerator");
|
|
3155
|
+
o(this, "fileHandler");
|
|
3156
|
+
this.dataExtractor = new YA(), this.contentGenerator = new OA(), this.fileHandler = new VA();
|
|
3121
3157
|
}
|
|
3122
3158
|
/**
|
|
3123
3159
|
* Applies default values to image export options
|
|
@@ -3203,38 +3239,38 @@ class OA {
|
|
|
3203
3239
|
class S {
|
|
3204
3240
|
constructor(A = null, e = {}) {
|
|
3205
3241
|
/** The element to capture content from (optional for standalone mode) */
|
|
3206
|
-
|
|
3242
|
+
o(this, "captureSource");
|
|
3207
3243
|
/** Our WebGL overlay canvas manager */
|
|
3208
|
-
|
|
3244
|
+
o(this, "textmodeCanvas");
|
|
3209
3245
|
/** Core WebGL renderer */
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
|
|
3214
|
-
|
|
3246
|
+
o(this, "_renderer");
|
|
3247
|
+
o(this, "_canvasFramebuffer");
|
|
3248
|
+
o(this, "_font");
|
|
3249
|
+
o(this, "_grid");
|
|
3250
|
+
o(this, "resizeObserver");
|
|
3215
3251
|
// Auto-rendering properties
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3252
|
+
o(this, "_mode");
|
|
3253
|
+
o(this, "_frameRateLimit");
|
|
3254
|
+
o(this, "animationFrameId", null);
|
|
3255
|
+
o(this, "lastFrameTime", 0);
|
|
3256
|
+
o(this, "frameInterval");
|
|
3257
|
+
o(this, "_isLooping", !0);
|
|
3258
|
+
o(this, "_frameRate", 0);
|
|
3259
|
+
o(this, "lastRenderTime", 0);
|
|
3260
|
+
o(this, "_frameCount", 0);
|
|
3225
3261
|
// Frame rate measurement smoothing
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3262
|
+
o(this, "frameTimeHistory", []);
|
|
3263
|
+
o(this, "frameTimeHistorySize", 10);
|
|
3264
|
+
o(this, "_pipeline");
|
|
3265
|
+
o(this, "_isDisposed", !1);
|
|
3230
3266
|
// Standalone canvas properties
|
|
3231
|
-
|
|
3232
|
-
|
|
3267
|
+
o(this, "_standalone", !1);
|
|
3268
|
+
o(this, "_drawCallback", () => {
|
|
3233
3269
|
});
|
|
3234
|
-
|
|
3270
|
+
o(this, "_resizedCallback", () => {
|
|
3235
3271
|
});
|
|
3236
|
-
|
|
3237
|
-
|
|
3272
|
+
o(this, "_windowResizeListener", null);
|
|
3273
|
+
o(this, "_printDebug", !1);
|
|
3238
3274
|
this.captureSource = A, this._standalone = A === null, this._mode = e.renderMode ?? "auto", this._frameRateLimit = e.frameRate ?? 60, this.frameInterval = 1e3 / this._frameRateLimit;
|
|
3239
3275
|
}
|
|
3240
3276
|
/**
|
|
@@ -3245,11 +3281,14 @@ class S {
|
|
|
3245
3281
|
*/
|
|
3246
3282
|
static async create(A = null, e = {}) {
|
|
3247
3283
|
const t = new S(A, e), r = t._standalone ? e : void 0;
|
|
3248
|
-
t.textmodeCanvas = new DA(t.captureSource, t._standalone, r), t._renderer = new
|
|
3284
|
+
t.textmodeCanvas = new DA(t.captureSource, t._standalone, r), t._renderer = new lA(t.textmodeCanvas.getWebGLContext());
|
|
3249
3285
|
let i, s;
|
|
3250
3286
|
t._standalone ? (i = e.width || 800, s = e.height || 600) : (i = t.textmodeCanvas.width || 800, s = t.textmodeCanvas.height || 600), t._canvasFramebuffer = t._renderer.createFramebuffer(i, s), t._font = new CA(t._renderer, e.fontSize ?? 16), await t._font.initialize(e.fontSource);
|
|
3251
|
-
const
|
|
3252
|
-
return t._grid = new mA(t.textmodeCanvas.canvas,
|
|
3287
|
+
const n = t._font.maxGlyphDimensions;
|
|
3288
|
+
return t._grid = new mA(t.textmodeCanvas.canvas, n.width, n.height), t._pipeline = new FA(t._renderer, t._font, t._grid), t.setupEventListeners(), t._standalone && (t.textmodeCanvas.onTransformChange = () => {
|
|
3289
|
+
const g = t.textmodeCanvas.getEffectiveRenderingDimensions();
|
|
3290
|
+
t._renderer.resetViewport(g.width, g.height), t._mode === "auto" && t.render();
|
|
3291
|
+
}), t.startAutoRendering(), t;
|
|
3253
3292
|
}
|
|
3254
3293
|
setupEventListeners() {
|
|
3255
3294
|
this._windowResizeListener = () => {
|
|
@@ -3351,7 +3390,7 @@ class S {
|
|
|
3351
3390
|
* ```
|
|
3352
3391
|
*/
|
|
3353
3392
|
toSVG(A = {}) {
|
|
3354
|
-
return new
|
|
3393
|
+
return new X().generateSVG(this, A);
|
|
3355
3394
|
}
|
|
3356
3395
|
/**
|
|
3357
3396
|
* Export the current textmode rendering to an SVG file.
|
|
@@ -3375,7 +3414,7 @@ class S {
|
|
|
3375
3414
|
* ```
|
|
3376
3415
|
*/
|
|
3377
3416
|
saveSVG(A = {}) {
|
|
3378
|
-
new
|
|
3417
|
+
new X().saveSVG(this, A);
|
|
3379
3418
|
}
|
|
3380
3419
|
/**
|
|
3381
3420
|
* Export the current textmode rendering to an image file.
|
|
@@ -3406,7 +3445,7 @@ class S {
|
|
|
3406
3445
|
* ```
|
|
3407
3446
|
*/
|
|
3408
3447
|
async saveCanvas(A, e = "png", t = {}) {
|
|
3409
|
-
await new
|
|
3448
|
+
await new kA().saveImage(this.textmodeCanvas, {
|
|
3410
3449
|
...t,
|
|
3411
3450
|
filename: A,
|
|
3412
3451
|
format: e
|
|
@@ -3490,7 +3529,12 @@ class S {
|
|
|
3490
3529
|
}
|
|
3491
3530
|
}
|
|
3492
3531
|
resize() {
|
|
3493
|
-
this.textmodeCanvas.resize(), this._canvasFramebuffer.resize(this.textmodeCanvas.width, this.textmodeCanvas.height), this._grid.resize(), this._pipeline.resize(), this.
|
|
3532
|
+
if (this.textmodeCanvas.resize(), this._canvasFramebuffer.resize(this.textmodeCanvas.width, this.textmodeCanvas.height), this._grid.resize(), this._pipeline.resize(), this._standalone) {
|
|
3533
|
+
const A = this.textmodeCanvas.getEffectiveRenderingDimensions();
|
|
3534
|
+
this._renderer.resetViewport(A.width, A.height);
|
|
3535
|
+
} else
|
|
3536
|
+
this._renderer.resetViewport();
|
|
3537
|
+
this._mode !== "manual" && this.render();
|
|
3494
3538
|
}
|
|
3495
3539
|
/**
|
|
3496
3540
|
* Start automatic rendering
|
|
@@ -3724,11 +3768,16 @@ class S {
|
|
|
3724
3768
|
* ```
|
|
3725
3769
|
*/
|
|
3726
3770
|
fontSize(A) {
|
|
3727
|
-
f.validate(
|
|
3771
|
+
if (f.validate(
|
|
3728
3772
|
typeof A == "number" && A > 0,
|
|
3729
3773
|
"Font size must be a positive number greater than 0.",
|
|
3730
3774
|
{ method: "fontSize", providedValue: A }
|
|
3731
|
-
) && this._font.fontSize !== A
|
|
3775
|
+
) && this._font.fontSize !== A)
|
|
3776
|
+
if (this._font.setFontSize(A), this._grid.resizeCellPixelDimensions(this._font.maxGlyphDimensions.width, this._font.maxGlyphDimensions.height), this._pipeline.resize(), this._standalone) {
|
|
3777
|
+
const e = this.textmodeCanvas.getEffectiveRenderingDimensions();
|
|
3778
|
+
this._renderer.resetViewport(e.width, e.height);
|
|
3779
|
+
} else
|
|
3780
|
+
this._renderer.resetViewport();
|
|
3732
3781
|
}
|
|
3733
3782
|
/**
|
|
3734
3783
|
* Set a draw callback function that will be executed before each render.
|
|
@@ -3795,7 +3844,12 @@ class S {
|
|
|
3795
3844
|
* @param height The new height of the canvas.
|
|
3796
3845
|
*/
|
|
3797
3846
|
resizeCanvas(A, e) {
|
|
3798
|
-
this.textmodeCanvas.resize(A, e), this._canvasFramebuffer.resize(this.textmodeCanvas.width, this.textmodeCanvas.height), this._grid.resize(), this._pipeline.resize(), this.
|
|
3847
|
+
if (this.textmodeCanvas.resize(A, e), this._canvasFramebuffer.resize(this.textmodeCanvas.width, this.textmodeCanvas.height), this._grid.resize(), this._pipeline.resize(), this._standalone) {
|
|
3848
|
+
const t = this.textmodeCanvas.getEffectiveRenderingDimensions();
|
|
3849
|
+
this._renderer.resetViewport(t.width, t.height);
|
|
3850
|
+
} else
|
|
3851
|
+
this._renderer.resetViewport();
|
|
3852
|
+
this._mode !== "manual" && this.render();
|
|
3799
3853
|
}
|
|
3800
3854
|
/**
|
|
3801
3855
|
* @inheritDoc TextmodeConversionPipeline.get
|
|
@@ -4406,7 +4460,7 @@ class N {
|
|
|
4406
4460
|
* ```
|
|
4407
4461
|
*/
|
|
4408
4462
|
static get version() {
|
|
4409
|
-
return "0.1.6-beta.
|
|
4463
|
+
return "0.1.6-beta.2";
|
|
4410
4464
|
}
|
|
4411
4465
|
constructor() {
|
|
4412
4466
|
throw new Error("Textmode is a static class and cannot be instantiated.");
|
|
@@ -4414,11 +4468,11 @@ class N {
|
|
|
4414
4468
|
}
|
|
4415
4469
|
const HA = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4416
4470
|
__proto__: null
|
|
4417
|
-
}, Symbol.toStringTag, { value: "Module" })), NA = N.create,
|
|
4471
|
+
}, Symbol.toStringTag, { value: "Module" })), NA = N.create, WA = N.setErrorLevel, XA = N.version;
|
|
4418
4472
|
export {
|
|
4419
4473
|
DA as TextmodeCanvas,
|
|
4420
4474
|
FA as TextmodeConversionPipeline,
|
|
4421
|
-
|
|
4475
|
+
nA as TextmodeErrorLevel,
|
|
4422
4476
|
CA as TextmodeFont,
|
|
4423
4477
|
mA as TextmodeGrid,
|
|
4424
4478
|
S as Textmodifier,
|
|
@@ -4426,7 +4480,7 @@ export {
|
|
|
4426
4480
|
NA as create,
|
|
4427
4481
|
N as default,
|
|
4428
4482
|
HA as export,
|
|
4429
|
-
|
|
4483
|
+
WA as setErrorLevel,
|
|
4430
4484
|
N as textmode,
|
|
4431
|
-
|
|
4485
|
+
XA as version
|
|
4432
4486
|
};
|