textmode.js 0.1.6-beta.3 → 0.1.6-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/textmode.esm.js +566 -649
- package/dist/textmode.esm.min.js +340 -423
- package/dist/textmode.umd.js +13 -13
- package/dist/textmode.umd.min.js +13 -13
- package/dist/types/rendering/webgl/Framebuffer.d.ts +11 -0
- package/dist/types/rendering/webgl/Renderer.d.ts +12 -0
- package/dist/types/rendering/webgl/StateCache.d.ts +6 -0
- package/package.json +1 -1
package/dist/textmode.esm.min.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var o = (h, e, t) =>
|
|
4
|
-
class
|
|
1
|
+
var ee = Object.defineProperty;
|
|
2
|
+
var te = (h, e, t) => e in h ? ee(h, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : h[e] = t;
|
|
3
|
+
var o = (h, e, t) => te(h, typeof e != "symbol" ? e + "" : e, t);
|
|
4
|
+
class x extends Error {
|
|
5
5
|
constructor(t, r, i = {}) {
|
|
6
|
-
const s =
|
|
6
|
+
const s = x.createFormattedMessage(t, i);
|
|
7
7
|
super(s);
|
|
8
8
|
o(this, "originalError");
|
|
9
9
|
o(this, "context");
|
|
@@ -19,7 +19,7 @@ class F extends Error {
|
|
|
19
19
|
|
|
20
20
|
📋 Context:`;
|
|
21
21
|
for (const [s, a] of Object.entries(r)) {
|
|
22
|
-
const n =
|
|
22
|
+
const n = x.formatValue(a);
|
|
23
23
|
i += `
|
|
24
24
|
- ${s}: ${n}`;
|
|
25
25
|
}
|
|
@@ -38,16 +38,16 @@ class F extends Error {
|
|
|
38
38
|
if (typeof t == "string") return `"${t}"`;
|
|
39
39
|
if (typeof t == "number" || typeof t == "boolean") return String(t);
|
|
40
40
|
if (Array.isArray(t))
|
|
41
|
-
return t.length === 0 ? "[]" : t.length <= 5 ? `[${t.map((r) =>
|
|
41
|
+
return t.length === 0 ? "[]" : t.length <= 5 ? `[${t.map((r) => x.formatValue(r)).join(", ")}]` : `[${t.slice(0, 3).map((r) => x.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((a) => `${a}: ${
|
|
44
|
+
return r.length === 0 ? "{}" : r.length <= 3 ? `{ ${r.map((a) => `${a}: ${x.formatValue(t[a])}`).join(", ")} }` : `{ ${r.slice(0, 2).map((s) => `${s}: ${x.formatValue(t[s])}`).join(", ")}, ... +${r.length - 2} more }`;
|
|
45
45
|
}
|
|
46
46
|
return String(t);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
var
|
|
50
|
-
const
|
|
49
|
+
var re = /* @__PURE__ */ ((h) => (h[h.SILENT = 0] = "SILENT", h[h.WARNING = 1] = "WARNING", h[h.ERROR = 2] = "ERROR", h[h.THROW = 3] = "THROW", h))(re || {});
|
|
50
|
+
const A = class A {
|
|
51
51
|
constructor() {
|
|
52
52
|
o(this, "_options", {
|
|
53
53
|
globalLevel: 3
|
|
@@ -55,7 +55,7 @@ const E = class E {
|
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
57
|
static getInstance() {
|
|
58
|
-
return
|
|
58
|
+
return A._instance || (A._instance = new A()), A._instance;
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
61
|
* Handle an error based on the configured settings
|
|
@@ -71,15 +71,15 @@ const E = class E {
|
|
|
71
71
|
return console.group(
|
|
72
72
|
`%c${i} 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(x.createFormattedMessage(e, t)), console.groupEnd(), !1;
|
|
75
75
|
case 2:
|
|
76
76
|
return console.group(
|
|
77
77
|
`%c${i} 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(x.createFormattedMessage(e, t)), console.groupEnd(), !1;
|
|
80
80
|
case 3:
|
|
81
81
|
default:
|
|
82
|
-
const s = new
|
|
82
|
+
const s = new x(e, r, t);
|
|
83
83
|
throw console.group(
|
|
84
84
|
`%c${i} Oops! (╯°□°)╯︵ Something went wrong in your code.`,
|
|
85
85
|
"color: #d32f2f; font-weight: bold; background: #ffcdd2; padding: 2px 6px; border-radius: 3px;"
|
|
@@ -103,10 +103,19 @@ const E = class E {
|
|
|
103
103
|
this._options.globalLevel = e;
|
|
104
104
|
}
|
|
105
105
|
};
|
|
106
|
-
o(
|
|
107
|
-
let
|
|
108
|
-
const
|
|
109
|
-
|
|
106
|
+
o(A, "_instance", null);
|
|
107
|
+
let z = A;
|
|
108
|
+
const _ = z.getInstance(), Z = /* @__PURE__ */ new WeakMap(), ie = /* @__PURE__ */ new WeakMap();
|
|
109
|
+
function P(h, e) {
|
|
110
|
+
Z.set(h, e);
|
|
111
|
+
}
|
|
112
|
+
function j(h) {
|
|
113
|
+
return Z.get(h);
|
|
114
|
+
}
|
|
115
|
+
function B(h, e) {
|
|
116
|
+
ie.set(h, e);
|
|
117
|
+
}
|
|
118
|
+
const I = class I {
|
|
110
119
|
constructor(e, t, r = t, i = {}) {
|
|
111
120
|
o(this, "gl");
|
|
112
121
|
o(this, "_framebuffer");
|
|
@@ -116,6 +125,8 @@ class oe {
|
|
|
116
125
|
o(this, "options");
|
|
117
126
|
o(this, "previousState", null);
|
|
118
127
|
o(this, "_pixels", null);
|
|
128
|
+
// Tracks the last upload origin; no longer required for rendering since we flip at upload time
|
|
129
|
+
o(this, "_isFromCanvasSource", !1);
|
|
119
130
|
this.gl = e, this._width = t, this._height = r, this.options = {
|
|
120
131
|
filter: "nearest",
|
|
121
132
|
wrap: "clamp",
|
|
@@ -124,6 +135,20 @@ class oe {
|
|
|
124
135
|
...i
|
|
125
136
|
}, this._texture = this.createTexture(), this._framebuffer = e.createFramebuffer(), this.attachTexture();
|
|
126
137
|
}
|
|
138
|
+
getMaxTextureUnits() {
|
|
139
|
+
let e = I.maxTextureUnitsMap.get(this.gl);
|
|
140
|
+
return e === void 0 && (e = this.gl.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS), I.maxTextureUnitsMap.set(this.gl, e)), e;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Unbind the provided texture from any texture unit where it is currently bound.
|
|
144
|
+
* This prevents framebuffer-texture feedback loops when rendering to this framebuffer.
|
|
145
|
+
*/
|
|
146
|
+
unbindTextureAcrossUnits(e) {
|
|
147
|
+
const t = this.gl, r = t.getParameter(t.ACTIVE_TEXTURE), i = this.getMaxTextureUnits();
|
|
148
|
+
for (let s = 0; s < i; s++)
|
|
149
|
+
t.activeTexture(t.TEXTURE0 + s), t.getParameter(t.TEXTURE_BINDING_2D) === e && t.bindTexture(t.TEXTURE_2D, null);
|
|
150
|
+
t.activeTexture(r);
|
|
151
|
+
}
|
|
127
152
|
createTexture() {
|
|
128
153
|
const { gl: e } = this, t = e.createTexture();
|
|
129
154
|
e.bindTexture(e.TEXTURE_2D, t);
|
|
@@ -143,14 +168,18 @@ class oe {
|
|
|
143
168
|
*/
|
|
144
169
|
update(e) {
|
|
145
170
|
const { gl: t } = this;
|
|
146
|
-
e instanceof HTMLVideoElement && e.readyState < 2
|
|
171
|
+
if (e instanceof HTMLVideoElement && e.readyState < 2)
|
|
172
|
+
return;
|
|
173
|
+
t.bindTexture(t.TEXTURE_2D, this._texture);
|
|
174
|
+
const r = t.getParameter(t.UNPACK_FLIP_Y_WEBGL);
|
|
175
|
+
t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL, 1), t.texImage2D(t.TEXTURE_2D, 0, t.RGBA, t.RGBA, t.UNSIGNED_BYTE, e), t.pixelStorei(t.UNPACK_FLIP_Y_WEBGL, r ? 1 : 0), t.bindTexture(t.TEXTURE_2D, null), this._isFromCanvasSource = !1;
|
|
147
176
|
}
|
|
148
177
|
/**
|
|
149
178
|
* Update the framebuffer texture with pixel data
|
|
150
179
|
*/
|
|
151
180
|
updatePixels(e, t, r) {
|
|
152
181
|
const { gl: i } = this;
|
|
153
|
-
i.bindTexture(i.TEXTURE_2D, this._texture), i.texImage2D(i.TEXTURE_2D, 0, i.RGBA, t, r, 0, i.RGBA, i.UNSIGNED_BYTE, e), i.bindTexture(i.TEXTURE_2D, null);
|
|
182
|
+
i.bindTexture(i.TEXTURE_2D, this._texture), i.texImage2D(i.TEXTURE_2D, 0, i.RGBA, t, r, 0, i.RGBA, i.UNSIGNED_BYTE, e), i.bindTexture(i.TEXTURE_2D, null), this._isFromCanvasSource = !1;
|
|
154
183
|
}
|
|
155
184
|
/**
|
|
156
185
|
* Resize the framebuffer
|
|
@@ -167,7 +196,7 @@ class oe {
|
|
|
167
196
|
this.previousState = {
|
|
168
197
|
framebuffer: e.getParameter(e.FRAMEBUFFER_BINDING),
|
|
169
198
|
viewport: e.getParameter(e.VIEWPORT)
|
|
170
|
-
}, e.bindFramebuffer(e.FRAMEBUFFER, this._framebuffer), e.viewport(0, 0, this._width, this._height);
|
|
199
|
+
}, e.bindFramebuffer(e.FRAMEBUFFER, this._framebuffer), e.viewport(0, 0, this._width, this._height), this.unbindTextureAcrossUnits(this._texture), B(e, !0), P(e, [0, 0, this._width, this._height]), this._isFromCanvasSource = !1;
|
|
171
200
|
}
|
|
172
201
|
/**
|
|
173
202
|
* End rendering to this framebuffer and restore previous state
|
|
@@ -175,7 +204,7 @@ class oe {
|
|
|
175
204
|
end() {
|
|
176
205
|
if (!this.previousState) return;
|
|
177
206
|
const { gl: e } = this;
|
|
178
|
-
e.bindFramebuffer(e.FRAMEBUFFER, this.previousState.framebuffer), e.viewport(...this.previousState.viewport), this.previousState = null;
|
|
207
|
+
e.bindFramebuffer(e.FRAMEBUFFER, this.previousState.framebuffer), e.viewport(...this.previousState.viewport), B(e, !!this.previousState.framebuffer), P(e, this.previousState.viewport), this.previousState = null;
|
|
179
208
|
}
|
|
180
209
|
/**
|
|
181
210
|
* Load pixel data from the framebuffer into the pixels array
|
|
@@ -224,247 +253,14 @@ class oe {
|
|
|
224
253
|
get pixels() {
|
|
225
254
|
return this._pixels;
|
|
226
255
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
o(this, "gl");
|
|
231
|
-
o(this, "x");
|
|
232
|
-
o(this, "y");
|
|
233
|
-
this.gl = e, this.x = t, this.y = r;
|
|
256
|
+
/** True if the last content update came from a canvas/video or raw pixels (top-left origin). False if rendered via FBO (bottom-left). */
|
|
257
|
+
get isFromCanvasSource() {
|
|
258
|
+
return this._isFromCanvasSource;
|
|
234
259
|
}
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
o(this, "gl");
|
|
240
|
-
/** The vertex buffer containing position and texture coordinates */
|
|
241
|
-
o(this, "vertexBuffer");
|
|
242
|
-
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
243
|
-
o(this, "vertexCount", 6);
|
|
244
|
-
/** Bytes per vertex: depends on position format (vec2 vs vec3) */
|
|
245
|
-
o(this, "bytesPerVertex");
|
|
246
|
-
this.gl = e, this.bytesPerVertex = 16;
|
|
247
|
-
const a = e.getParameter(e.VIEWPORT), n = a[2], l = a[3], c = e.getParameter(e.FRAMEBUFFER_BINDING) !== null, u = t / n * 2 - 1, d = (t + i) / n * 2 - 1;
|
|
248
|
-
let f, g;
|
|
249
|
-
c ? (f = r / l * 2 - 1, g = (r + s) / l * 2 - 1) : (f = 1 - r / l * 2, g = 1 - (r + s) / l * 2);
|
|
250
|
-
let _, p, b, C;
|
|
251
|
-
_ = u, b = d, p = f, C = g;
|
|
252
|
-
const x = this.generateVertices(_, p, b, C);
|
|
253
|
-
this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, x, e.STATIC_DRAW);
|
|
254
|
-
}
|
|
255
|
-
/**
|
|
256
|
-
* Generate vertex data for the rectangle with texture coordinates
|
|
257
|
-
* @private
|
|
258
|
-
*/
|
|
259
|
-
generateVertices(e, t, r, i) {
|
|
260
|
-
return new Float32Array([
|
|
261
|
-
e,
|
|
262
|
-
i,
|
|
263
|
-
0,
|
|
264
|
-
1,
|
|
265
|
-
// bottom-left
|
|
266
|
-
r,
|
|
267
|
-
i,
|
|
268
|
-
1,
|
|
269
|
-
1,
|
|
270
|
-
// bottom-right
|
|
271
|
-
e,
|
|
272
|
-
t,
|
|
273
|
-
0,
|
|
274
|
-
0,
|
|
275
|
-
// top-left
|
|
276
|
-
e,
|
|
277
|
-
t,
|
|
278
|
-
0,
|
|
279
|
-
0,
|
|
280
|
-
// top-left
|
|
281
|
-
r,
|
|
282
|
-
i,
|
|
283
|
-
1,
|
|
284
|
-
1,
|
|
285
|
-
// bottom-right
|
|
286
|
-
r,
|
|
287
|
-
t,
|
|
288
|
-
1,
|
|
289
|
-
0
|
|
290
|
-
// top-right
|
|
291
|
-
]);
|
|
292
|
-
}
|
|
293
|
-
/**
|
|
294
|
-
* Render the rectangle using position and texture coordinate attributes
|
|
295
|
-
*/
|
|
296
|
-
render() {
|
|
297
|
-
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
298
|
-
const e = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
|
|
299
|
-
let t = this.gl.getAttribLocation(e, "a_position"), r = this.gl.getAttribLocation(e, "a_texCoord");
|
|
300
|
-
this.gl.enableVertexAttribArray(t), this.gl.vertexAttribPointer(t, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 0), this.gl.enableVertexAttribArray(r), this.gl.vertexAttribPointer(r, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 8), this.gl.drawArrays(this.gl.TRIANGLES, 0, this.vertexCount), this.gl.disableVertexAttribArray(t), this.gl.disableVertexAttribArray(r);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
class he extends Q {
|
|
304
|
-
constructor(t, r, i, s, a) {
|
|
305
|
-
super(t, r, i);
|
|
306
|
-
o(this, "width");
|
|
307
|
-
o(this, "height");
|
|
308
|
-
this.width = s, this.height = a;
|
|
309
|
-
}
|
|
310
|
-
/**
|
|
311
|
-
* Render the filled rectangle using the existing Rectangle geometry.
|
|
312
|
-
*/
|
|
313
|
-
renderFill() {
|
|
314
|
-
new M(this.gl, this.x, this.y, this.width, this.height).render();
|
|
315
|
-
}
|
|
316
|
-
/**
|
|
317
|
-
* Render the stroke rectangle as four separate Rectangle instances for each edge.
|
|
318
|
-
* This approach ensures clean corners with proper overlap and leverages existing geometry.
|
|
319
|
-
* @param weight The stroke thickness in pixels
|
|
320
|
-
*/
|
|
321
|
-
renderStroke(t) {
|
|
322
|
-
if (t <= 0) return;
|
|
323
|
-
const r = new M(this.gl, this.x, this.y, this.width, t), i = new M(this.gl, this.x + this.width - t, this.y, t, this.height), s = new M(this.gl, this.x, this.y + this.height - t, this.width, t), a = new M(this.gl, this.x, this.y, t, this.height);
|
|
324
|
-
r.render(), i.render(), s.render(), a.render();
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
class le {
|
|
328
|
-
constructor(e, t, r, i, s, a) {
|
|
329
|
-
/** The WebGL rendering context */
|
|
330
|
-
o(this, "gl");
|
|
331
|
-
/** The vertex buffer containing position and texture coordinates */
|
|
332
|
-
o(this, "vertexBuffer");
|
|
333
|
-
/** The number of vertices in this geometry (always 6 for two triangles) */
|
|
334
|
-
o(this, "vertexCount", 6);
|
|
335
|
-
/** Bytes per vertex: vec2+vec2 = 16 bytes */
|
|
336
|
-
o(this, "bytesPerVertex");
|
|
337
|
-
this.gl = e, this.bytesPerVertex = 16;
|
|
338
|
-
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);
|
|
339
|
-
if (g === 0) {
|
|
340
|
-
const ie = this.generateVertices(0, 0, 0, 0);
|
|
341
|
-
this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, ie, e.STATIC_DRAW);
|
|
342
|
-
return;
|
|
343
|
-
}
|
|
344
|
-
const _ = d / g, b = -(f / g), C = _, x = a / 2, w = t + b * x, A = r + C * x, R = t - b * x, S = r - C * x, P = i + b * x, D = s + C * x, Z = i - b * x, W = s - C * x, J = w / l * 2 - 1, K = R / l * 2 - 1, ee = P / l * 2 - 1, te = Z / l * 2 - 1;
|
|
345
|
-
let B, G, V, k;
|
|
346
|
-
u ? (B = A / c * 2 - 1, G = S / c * 2 - 1, V = D / c * 2 - 1, k = W / c * 2 - 1) : (B = 1 - A / c * 2, G = 1 - S / c * 2, V = 1 - D / c * 2, k = 1 - W / c * 2);
|
|
347
|
-
const re = this.generateLineVertices(
|
|
348
|
-
J,
|
|
349
|
-
B,
|
|
350
|
-
K,
|
|
351
|
-
G,
|
|
352
|
-
ee,
|
|
353
|
-
V,
|
|
354
|
-
te,
|
|
355
|
-
k
|
|
356
|
-
);
|
|
357
|
-
this.vertexBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.vertexBuffer), e.bufferData(e.ARRAY_BUFFER, re, e.STATIC_DRAW);
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* Generate vertex data for a rectangle representing the line with texture coordinates
|
|
361
|
-
* @private
|
|
362
|
-
*/
|
|
363
|
-
generateVertices(e, t, r, i) {
|
|
364
|
-
return new Float32Array([
|
|
365
|
-
e,
|
|
366
|
-
i,
|
|
367
|
-
0,
|
|
368
|
-
1,
|
|
369
|
-
// bottom-left
|
|
370
|
-
r,
|
|
371
|
-
i,
|
|
372
|
-
1,
|
|
373
|
-
1,
|
|
374
|
-
// bottom-right
|
|
375
|
-
e,
|
|
376
|
-
t,
|
|
377
|
-
0,
|
|
378
|
-
0,
|
|
379
|
-
// top-left
|
|
380
|
-
e,
|
|
381
|
-
t,
|
|
382
|
-
0,
|
|
383
|
-
0,
|
|
384
|
-
// top-left
|
|
385
|
-
r,
|
|
386
|
-
i,
|
|
387
|
-
1,
|
|
388
|
-
1,
|
|
389
|
-
// bottom-right
|
|
390
|
-
r,
|
|
391
|
-
t,
|
|
392
|
-
1,
|
|
393
|
-
0
|
|
394
|
-
// top-right
|
|
395
|
-
]);
|
|
396
|
-
}
|
|
397
|
-
/**
|
|
398
|
-
* Generate vertex data for the line rectangle with texture coordinates
|
|
399
|
-
* Uses the four corners calculated based on line direction and thickness
|
|
400
|
-
* @private
|
|
401
|
-
*/
|
|
402
|
-
generateLineVertices(e, t, r, i, s, a, n, l) {
|
|
403
|
-
return new Float32Array([
|
|
404
|
-
e,
|
|
405
|
-
t,
|
|
406
|
-
0,
|
|
407
|
-
0,
|
|
408
|
-
// corner1 (start + perpendicular)
|
|
409
|
-
r,
|
|
410
|
-
i,
|
|
411
|
-
0,
|
|
412
|
-
1,
|
|
413
|
-
// corner2 (start - perpendicular)
|
|
414
|
-
s,
|
|
415
|
-
a,
|
|
416
|
-
1,
|
|
417
|
-
0,
|
|
418
|
-
// corner3 (end + perpendicular)
|
|
419
|
-
r,
|
|
420
|
-
i,
|
|
421
|
-
0,
|
|
422
|
-
1,
|
|
423
|
-
// corner2 (start - perpendicular)
|
|
424
|
-
n,
|
|
425
|
-
l,
|
|
426
|
-
1,
|
|
427
|
-
1,
|
|
428
|
-
// corner4 (end - perpendicular)
|
|
429
|
-
s,
|
|
430
|
-
a,
|
|
431
|
-
1,
|
|
432
|
-
0
|
|
433
|
-
// corner3 (end + perpendicular)
|
|
434
|
-
]);
|
|
435
|
-
}
|
|
436
|
-
/**
|
|
437
|
-
* Render the line using position and texture coordinate attributes
|
|
438
|
-
*/
|
|
439
|
-
render() {
|
|
440
|
-
this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertexBuffer);
|
|
441
|
-
const e = this.gl.getParameter(this.gl.CURRENT_PROGRAM);
|
|
442
|
-
let t = this.gl.getAttribLocation(e, "a_position"), r = this.gl.getAttribLocation(e, "a_texCoord");
|
|
443
|
-
this.gl.enableVertexAttribArray(t), this.gl.vertexAttribPointer(t, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 0), this.gl.enableVertexAttribArray(r), this.gl.vertexAttribPointer(r, 2, this.gl.FLOAT, !1, this.bytesPerVertex, 8), this.gl.drawArrays(this.gl.TRIANGLES, 0, this.vertexCount), this.gl.disableVertexAttribArray(t), this.gl.disableVertexAttribArray(r);
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
class ce extends Q {
|
|
447
|
-
constructor(t, r, i, s, a) {
|
|
448
|
-
super(t, r, i);
|
|
449
|
-
o(this, "x2");
|
|
450
|
-
o(this, "y2");
|
|
451
|
-
this.x2 = s, this.y2 = a;
|
|
452
|
-
}
|
|
453
|
-
/**
|
|
454
|
-
* Lines don't support fill rendering - this method does nothing.
|
|
455
|
-
* Lines are rendered only with stroke properties.
|
|
456
|
-
*/
|
|
457
|
-
renderFill() {
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* Render the line with the specified stroke weight.
|
|
461
|
-
* @param weight The stroke thickness in pixels
|
|
462
|
-
*/
|
|
463
|
-
renderStroke(t) {
|
|
464
|
-
if (t <= 0) return;
|
|
465
|
-
new le(this.gl, this.x, this.y, this.x2, this.y2, t).render();
|
|
466
|
-
}
|
|
467
|
-
}
|
|
260
|
+
};
|
|
261
|
+
/** Cache for MAX_TEXTURE_IMAGE_UNITS per-context */
|
|
262
|
+
o(I, "maxTextureUnitsMap", /* @__PURE__ */ new WeakMap());
|
|
263
|
+
let $ = I;
|
|
468
264
|
class y {
|
|
469
265
|
constructor(e, t, r) {
|
|
470
266
|
o(this, "gl");
|
|
@@ -612,13 +408,15 @@ class y {
|
|
|
612
408
|
this.textureUnitCounter = 0;
|
|
613
409
|
}
|
|
614
410
|
}
|
|
615
|
-
var T = "attribute vec2 a_position;attribute vec2 a_texCoord;varying vec2 v_uv;uniform float u_rotation;uniform vec2 u_center;uniform float u_aspectRatio;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){v_uv=a_texCoord;vec2 pos=a_position;pos-=u_center;pos.x*=u_aspectRatio;pos=rotate2D(-u_rotation)*pos;pos.x/=u_aspectRatio;pos+=u_center;gl_Position=vec4(pos,0.0,1.0);}",
|
|
616
|
-
class
|
|
411
|
+
var T = "attribute vec2 a_position;attribute vec2 a_texCoord;varying vec2 v_uv;uniform float u_rotation;uniform vec2 u_center;uniform float u_aspectRatio;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){v_uv=a_texCoord;vec2 pos=a_position;pos-=u_center;pos.x*=u_aspectRatio;pos=rotate2D(-u_rotation)*pos;pos.x/=u_aspectRatio;pos+=u_center;gl_Position=vec4(pos,0.0,1.0);}", se = "precision lowp float;uniform sampler2D u_texture;varying vec2 v_uv;void main(){gl_FragColor=texture2D(u_texture,v_uv);}", ae = "precision lowp float;uniform vec4 u_color;void main(){gl_FragColor=u_color;}";
|
|
412
|
+
class ne {
|
|
617
413
|
constructor(e) {
|
|
618
414
|
o(this, "gl");
|
|
619
415
|
o(this, "imageShader");
|
|
620
416
|
o(this, "solidColorShader");
|
|
621
417
|
o(this, "currentShader", null);
|
|
418
|
+
// Cached attrib locations for current program
|
|
419
|
+
o(this, "attribCache");
|
|
622
420
|
// Fill state management - default: white fill enabled
|
|
623
421
|
o(this, "currentFillColor", [1, 1, 1, 1]);
|
|
624
422
|
o(this, "fillMode", !0);
|
|
@@ -631,13 +429,18 @@ class fe {
|
|
|
631
429
|
// in degrees
|
|
632
430
|
// State stack for push/pop functionality
|
|
633
431
|
o(this, "stateStack", []);
|
|
634
|
-
|
|
432
|
+
// ----- Immediate-mode helpers that use a single static VBO (no per-call allocation) -----
|
|
433
|
+
o(this, "unitBuffer", null);
|
|
434
|
+
o(this, "bytesPerVertex", 16);
|
|
435
|
+
// vec2 + vec2
|
|
436
|
+
o(this, "scratchFramebuffer", null);
|
|
437
|
+
this.gl = e, this.imageShader = new y(this.gl, T, se), this.solidColorShader = new y(this.gl, T, ae), this.attribCache = /* @__PURE__ */ new Map(), 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), P(this.gl, [0, 0, this.gl.canvas.width, this.gl.canvas.height]), B(this.gl, !1);
|
|
635
438
|
}
|
|
636
439
|
/**
|
|
637
440
|
* Set the current shader
|
|
638
441
|
*/
|
|
639
442
|
shader(e) {
|
|
640
|
-
this.currentShader = e, e.use();
|
|
443
|
+
this.currentShader !== e && (this.currentShader = e, e.use());
|
|
641
444
|
}
|
|
642
445
|
/**
|
|
643
446
|
* Sets the fill color for subsequent rendering operations
|
|
@@ -729,7 +532,7 @@ class fe {
|
|
|
729
532
|
* across frames and be managed by push/pop or explicit calls.
|
|
730
533
|
*/
|
|
731
534
|
reset() {
|
|
732
|
-
this.currentShader = null, this.stateStack = [], this.currentRotation = 0
|
|
535
|
+
this.currentShader = null, this.stateStack = [], this.currentRotation = 0;
|
|
733
536
|
}
|
|
734
537
|
createShader(e, t) {
|
|
735
538
|
return new y(this.gl, e, t);
|
|
@@ -747,18 +550,22 @@ class fe {
|
|
|
747
550
|
* Draw a rectangle with the current fill and/or stroke settings
|
|
748
551
|
*/
|
|
749
552
|
rect(e, t, r, i) {
|
|
750
|
-
const s = new he(this.gl, e, t, r, i);
|
|
751
553
|
if (this.currentShader !== null) {
|
|
752
554
|
if (this.currentRotation !== 0) {
|
|
753
|
-
const { centerX:
|
|
754
|
-
this.setUniform("u_rotation",
|
|
555
|
+
const { centerX: f, centerY: g, radians: v, aspectRatio: p } = this.calculateRotationParams(e, t, r, i);
|
|
556
|
+
this.setUniform("u_rotation", v), this.setUniform("u_center", [f, g]), this.setUniform("u_aspectRatio", p);
|
|
755
557
|
} else
|
|
756
558
|
this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
|
|
757
|
-
|
|
559
|
+
this.drawRectImmediate(e, t, r, i), this.currentShader = null;
|
|
758
560
|
return;
|
|
759
561
|
}
|
|
760
|
-
const a = this.solidColorShader,
|
|
761
|
-
|
|
562
|
+
const a = this.solidColorShader, n = this.currentRotation !== 0;
|
|
563
|
+
let l = 0, c = 0, u = 0, d = 1;
|
|
564
|
+
if (n) {
|
|
565
|
+
const f = this.calculateRotationParams(e, t, r, i);
|
|
566
|
+
l = f.centerX, c = f.centerY, u = f.radians, d = f.aspectRatio;
|
|
567
|
+
}
|
|
568
|
+
this.fillMode && (this.shader(a), this.setUniform("u_color", this.currentFillColor), n && (this.setUniform("u_rotation", u), this.setUniform("u_center", [l, c]), this.setUniform("u_aspectRatio", d)), this.drawRectImmediate(e, t, r, i)), this.strokeMode && this.currentStrokeWeight > 0 && (this.shader(a), this.setUniform("u_color", this.currentStrokeColor), n && (this.setUniform("u_rotation", u), this.setUniform("u_center", [l, c]), this.setUniform("u_aspectRatio", d)), this.drawRectStrokeImmediate(e, t, r, i, this.currentStrokeWeight));
|
|
762
569
|
}
|
|
763
570
|
/**
|
|
764
571
|
* Draw a line from (x1, y1) to (x2, y2) with the current stroke settings.
|
|
@@ -769,35 +576,38 @@ class fe {
|
|
|
769
576
|
* @param y2 Y-coordinate of the line end point
|
|
770
577
|
*/
|
|
771
578
|
line(e, t, r, i) {
|
|
772
|
-
if (!this.strokeMode) return;
|
|
773
|
-
const s = new ce(this.gl, e, t, r, i);
|
|
774
579
|
if (this.currentShader !== null) {
|
|
580
|
+
const b = (e + r) / 2, w = (t + i) / 2, F = Math.abs(r - e) || 1, C = Math.abs(i - t) || 1;
|
|
775
581
|
if (this.currentRotation !== 0) {
|
|
776
|
-
const
|
|
777
|
-
this.setUniform("u_rotation", R), this.setUniform("u_center", [
|
|
582
|
+
const { centerX: U, centerY: S, radians: R, aspectRatio: E } = this.calculateRotationParams(b - F / 2, w - C / 2, F, C);
|
|
583
|
+
this.setUniform("u_rotation", R), this.setUniform("u_center", [U, S]), this.setUniform("u_aspectRatio", E);
|
|
778
584
|
} else
|
|
779
585
|
this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1);
|
|
780
|
-
|
|
586
|
+
const G = this.currentStrokeWeight > 0 ? this.currentStrokeWeight : 1;
|
|
587
|
+
this.drawLineImmediate(e, t, r, i, G), this.currentShader = null;
|
|
781
588
|
return;
|
|
782
589
|
}
|
|
783
|
-
|
|
784
|
-
|
|
590
|
+
if (!this.strokeMode || this.currentStrokeWeight <= 0) return;
|
|
591
|
+
const a = this.solidColorShader, n = (e + r) / 2, l = (t + i) / 2, c = Math.abs(r - e) || 1, u = Math.abs(i - t) || 1, d = this.currentRotation !== 0;
|
|
592
|
+
let f = 0, g = 0, v = 0, p = 1;
|
|
593
|
+
if (d) {
|
|
594
|
+
const b = this.calculateRotationParams(n - c / 2, l - u / 2, c, u);
|
|
595
|
+
f = b.centerX, g = b.centerY, v = b.radians, p = b.aspectRatio;
|
|
596
|
+
}
|
|
597
|
+
this.shader(a), this.setUniform("u_color", this.currentStrokeColor), d && (this.setUniform("u_rotation", v), this.setUniform("u_center", [f, g]), this.setUniform("u_aspectRatio", p)), this.drawLineImmediate(e, t, r, i, this.currentStrokeWeight);
|
|
785
598
|
}
|
|
786
599
|
/**
|
|
787
600
|
* Calculate rotation parameters for built-in shaders (NDC coordinates)
|
|
788
601
|
*/
|
|
789
602
|
calculateRotationParams(e, t, r, i) {
|
|
790
|
-
const s = this.gl.
|
|
791
|
-
|
|
792
|
-
c ? g = d / n * 2 - 1 : g = 1 - d / n * 2;
|
|
793
|
-
const _ = this.currentRotation * Math.PI / 180;
|
|
794
|
-
return { centerX: f, centerY: g, radians: _, aspectRatio: l };
|
|
603
|
+
const s = j(this.gl) || [0, 0, this.gl.canvas.width, this.gl.canvas.height], a = s[2], n = s[3], l = a / n, c = e + r / 2, u = t + i / 2, d = c / a * 2 - 1, f = 1 - u / n * 2, g = this.currentRotation * Math.PI / 180;
|
|
604
|
+
return { centerX: d, centerY: f, radians: g, aspectRatio: l };
|
|
795
605
|
}
|
|
796
606
|
/**
|
|
797
607
|
* Create a new framebuffer
|
|
798
608
|
*/
|
|
799
609
|
createFramebuffer(e, t, r = {}) {
|
|
800
|
-
return new
|
|
610
|
+
return new $(this.gl, e, t, r);
|
|
801
611
|
}
|
|
802
612
|
/**
|
|
803
613
|
* Fill the current framebuffer with a solid color
|
|
@@ -815,7 +625,7 @@ class fe {
|
|
|
815
625
|
* Ensure viewport matches canvas dimensions
|
|
816
626
|
*/
|
|
817
627
|
resetViewport() {
|
|
818
|
-
this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height);
|
|
628
|
+
this.gl.viewport(0, 0, this.gl.canvas.width, this.gl.canvas.height), P(this.gl, [0, 0, this.gl.canvas.width, this.gl.canvas.height]), B(this.gl, !1);
|
|
819
629
|
}
|
|
820
630
|
/**
|
|
821
631
|
* Get the WebGL context
|
|
@@ -828,20 +638,127 @@ class fe {
|
|
|
828
638
|
* This method is idempotent and safe to call multiple times.
|
|
829
639
|
*/
|
|
830
640
|
dispose() {
|
|
831
|
-
this.imageShader.dispose(), this.solidColorShader.dispose(), this.imageShader = null, this.solidColorShader = null, this.currentShader = null, this.stateStack = [];
|
|
641
|
+
this.scratchFramebuffer && (this.scratchFramebuffer.dispose(), this.scratchFramebuffer = null), this.imageShader.dispose(), this.solidColorShader.dispose(), this.imageShader = null, this.solidColorShader = null, this.currentShader = null, this.stateStack = [];
|
|
832
642
|
}
|
|
833
643
|
/**
|
|
834
644
|
* Render a framebuffer at a specific position with optional scaling
|
|
835
645
|
*/
|
|
836
646
|
image(e, t, r, i, s) {
|
|
647
|
+
const a = this.gl, n = i ?? e.width, l = s ?? e.height, c = a.getParameter(a.FRAMEBUFFER_BINDING);
|
|
648
|
+
if (c && e.framebuffer === c) {
|
|
649
|
+
(!this.scratchFramebuffer || this.scratchFramebuffer.width !== n || this.scratchFramebuffer.height !== l) && (this.scratchFramebuffer && this.scratchFramebuffer.dispose(), this.scratchFramebuffer = this.createFramebuffer(n, l)), this.scratchFramebuffer.begin(), this.clear(0, 0, 0, 0), this.shader(this.imageShader), this.setUniform("u_texture", e.texture), this.setUniform("u_rotation", 0), this.setUniform("u_center", [0, 0]), this.setUniform("u_aspectRatio", 1), this.drawRectImmediate(0, 0, n, l), this.scratchFramebuffer.end(), this.shader(this.imageShader);
|
|
650
|
+
const d = this.currentRotation !== 0 ? this.calculateRotationParams(t, r, n, l) : { centerX: 0, centerY: 0, radians: 0, aspectRatio: 1 };
|
|
651
|
+
this.setUniform("u_texture", this.scratchFramebuffer.texture), this.setUniform("u_rotation", d.radians), this.setUniform("u_center", [d.centerX, d.centerY]), this.setUniform("u_aspectRatio", d.aspectRatio), this.drawRectImmediate(t, r, n, l), a.bindTexture(a.TEXTURE_2D, null), this.currentShader = null;
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
837
654
|
this.shader(this.imageShader), this.setUniform("u_texture", e.texture);
|
|
838
|
-
const { centerX:
|
|
655
|
+
const u = this.currentRotation !== 0 ? this.calculateRotationParams(t, r, n, l) : { centerX: 0, centerY: 0, radians: 0, aspectRatio: 1 };
|
|
656
|
+
this.setUniform("u_rotation", u.radians), this.setUniform("u_center", [u.centerX, u.centerY]), this.setUniform("u_aspectRatio", u.aspectRatio), this.drawRectImmediate(t, r, n, l), a.bindTexture(a.TEXTURE_2D, null), this.currentShader = null;
|
|
657
|
+
}
|
|
658
|
+
ensureUnitBuffer() {
|
|
659
|
+
if (this.unitBuffer) return;
|
|
660
|
+
const e = this.gl;
|
|
661
|
+
this.unitBuffer = e.createBuffer(), e.bindBuffer(e.ARRAY_BUFFER, this.unitBuffer);
|
|
662
|
+
}
|
|
663
|
+
enableAttribs() {
|
|
664
|
+
const e = this.gl, t = e.getParameter(e.CURRENT_PROGRAM);
|
|
665
|
+
let r = this.attribCache.get(t);
|
|
666
|
+
return r || (r = {
|
|
667
|
+
a_position: e.getAttribLocation(t, "a_position"),
|
|
668
|
+
a_texCoord: e.getAttribLocation(t, "a_texCoord")
|
|
669
|
+
}, this.attribCache.set(t, r)), e.enableVertexAttribArray(r.a_position), e.vertexAttribPointer(r.a_position, 2, e.FLOAT, !1, this.bytesPerVertex, 0), e.enableVertexAttribArray(r.a_texCoord), e.vertexAttribPointer(r.a_texCoord, 2, e.FLOAT, !1, this.bytesPerVertex, 8), { positionLoc: r.a_position, texLoc: r.a_texCoord };
|
|
670
|
+
}
|
|
671
|
+
disableAttribs(e, t) {
|
|
672
|
+
const r = this.gl;
|
|
673
|
+
r.disableVertexAttribArray(e), r.disableVertexAttribArray(t);
|
|
674
|
+
}
|
|
675
|
+
uploadQuadNDC(e, t, r, i) {
|
|
676
|
+
const s = this.gl;
|
|
677
|
+
this.ensureUnitBuffer(), s.bindBuffer(s.ARRAY_BUFFER, this.unitBuffer);
|
|
678
|
+
const a = 0, n = 0, l = 1, c = 1, u = new Float32Array([
|
|
679
|
+
e,
|
|
680
|
+
i,
|
|
681
|
+
0,
|
|
682
|
+
a,
|
|
683
|
+
// bottom-left
|
|
684
|
+
r,
|
|
685
|
+
i,
|
|
686
|
+
1,
|
|
687
|
+
n,
|
|
688
|
+
// bottom-right
|
|
689
|
+
e,
|
|
690
|
+
t,
|
|
691
|
+
0,
|
|
692
|
+
l,
|
|
693
|
+
// top-left
|
|
694
|
+
e,
|
|
839
695
|
t,
|
|
696
|
+
0,
|
|
697
|
+
l,
|
|
698
|
+
// top-left
|
|
840
699
|
r,
|
|
841
|
-
i
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
700
|
+
i,
|
|
701
|
+
1,
|
|
702
|
+
n,
|
|
703
|
+
// bottom-right
|
|
704
|
+
r,
|
|
705
|
+
t,
|
|
706
|
+
1,
|
|
707
|
+
c
|
|
708
|
+
// top-right
|
|
709
|
+
]);
|
|
710
|
+
s.bufferData(s.ARRAY_BUFFER, u, s.DYNAMIC_DRAW);
|
|
711
|
+
}
|
|
712
|
+
toNDC(e, t) {
|
|
713
|
+
const r = this.gl, i = j(r) || [0, 0, r.canvas.width, r.canvas.height], s = i[2], a = i[3], n = e / s * 2 - 1, l = 1 - t / a * 2;
|
|
714
|
+
return { nx: n, ny: l };
|
|
715
|
+
}
|
|
716
|
+
drawRectImmediate(e, t, r, i) {
|
|
717
|
+
const s = this.toNDC(e, t), a = this.toNDC(e + r, t + i);
|
|
718
|
+
this.uploadQuadNDC(s.nx, s.ny, a.nx, a.ny);
|
|
719
|
+
const n = this.enableAttribs();
|
|
720
|
+
this.gl.drawArrays(this.gl.TRIANGLES, 0, 6), this.disableAttribs(n.positionLoc, n.texLoc);
|
|
721
|
+
}
|
|
722
|
+
drawRectStrokeImmediate(e, t, r, i, s) {
|
|
723
|
+
this.drawRectImmediate(e, t, r, s), this.drawRectImmediate(e + r - s, t, s, i), this.drawRectImmediate(e, t + i - s, r, s), this.drawRectImmediate(e, t, s, i);
|
|
724
|
+
}
|
|
725
|
+
drawLineImmediate(e, t, r, i, s) {
|
|
726
|
+
const a = r - e, n = i - t, l = Math.hypot(a, n);
|
|
727
|
+
if (l === 0) {
|
|
728
|
+
this.drawRectImmediate(e - s / 2, t - s / 2, s, s);
|
|
729
|
+
return;
|
|
730
|
+
}
|
|
731
|
+
const c = a / l, d = -(n / l), f = c, g = s / 2, v = e + d * g, p = t + f * g, b = e - d * g, w = t - f * g, F = r + d * g, C = i + f * g, G = r - d * g, U = i - f * g, S = this.toNDC(v, p), R = this.toNDC(b, w), E = this.toNDC(F, C), W = this.toNDC(G, U), M = this.gl;
|
|
732
|
+
this.ensureUnitBuffer(), M.bindBuffer(M.ARRAY_BUFFER, this.unitBuffer);
|
|
733
|
+
const J = new Float32Array([
|
|
734
|
+
S.nx,
|
|
735
|
+
S.ny,
|
|
736
|
+
0,
|
|
737
|
+
0,
|
|
738
|
+
R.nx,
|
|
739
|
+
R.ny,
|
|
740
|
+
0,
|
|
741
|
+
1,
|
|
742
|
+
E.nx,
|
|
743
|
+
E.ny,
|
|
744
|
+
1,
|
|
745
|
+
0,
|
|
746
|
+
R.nx,
|
|
747
|
+
R.ny,
|
|
748
|
+
0,
|
|
749
|
+
1,
|
|
750
|
+
W.nx,
|
|
751
|
+
W.ny,
|
|
752
|
+
1,
|
|
753
|
+
1,
|
|
754
|
+
E.nx,
|
|
755
|
+
E.ny,
|
|
756
|
+
1,
|
|
757
|
+
0
|
|
758
|
+
]);
|
|
759
|
+
M.bufferData(M.ARRAY_BUFFER, J, M.DYNAMIC_DRAW);
|
|
760
|
+
const Y = this.enableAttribs();
|
|
761
|
+
M.drawArrays(M.TRIANGLES, 0, 6), this.disableAttribs(Y.positionLoc, Y.texLoc);
|
|
845
762
|
}
|
|
846
763
|
}
|
|
847
764
|
var m = {};
|
|
@@ -859,8 +776,8 @@ m.parse = function(h) {
|
|
|
859
776
|
for (var f in u) {
|
|
860
777
|
var g = m.findTable(s, f, n);
|
|
861
778
|
if (g) {
|
|
862
|
-
var
|
|
863
|
-
p == null && (p = u[f].parseTab(s,
|
|
779
|
+
var v = g[0], p = l[v];
|
|
780
|
+
p == null && (p = u[f].parseTab(s, v, g[1], d)), d[f] = l[v] = p;
|
|
864
781
|
}
|
|
865
782
|
}
|
|
866
783
|
return d;
|
|
@@ -925,15 +842,15 @@ m.T.cmap = {
|
|
|
925
842
|
e += 2;
|
|
926
843
|
var f = i.readUint(h, e);
|
|
927
844
|
e += 4;
|
|
928
|
-
var g = "p" + u + "e" + d,
|
|
929
|
-
if (
|
|
930
|
-
|
|
845
|
+
var g = "p" + u + "e" + d, v = l.indexOf(f);
|
|
846
|
+
if (v == -1) {
|
|
847
|
+
v = r.tables.length;
|
|
931
848
|
var p = {};
|
|
932
849
|
l.push(f);
|
|
933
850
|
var b = p.format = s(h, f);
|
|
934
851
|
b == 4 ? p = a.parse4(h, f, p) : b == 12 && (p = a.parse12(h, f, p)), r.tables.push(p);
|
|
935
852
|
}
|
|
936
|
-
r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] =
|
|
853
|
+
r.ids[g] != null && console.log("multiple tables for one platform+encoding: " + g), r.ids[g] = v;
|
|
937
854
|
}
|
|
938
855
|
return r;
|
|
939
856
|
},
|
|
@@ -1047,13 +964,13 @@ m.T.glyf = {
|
|
|
1047
964
|
}
|
|
1048
965
|
a.xs = [];
|
|
1049
966
|
for (var n = 0; n < c; n++) {
|
|
1050
|
-
var g = (a.flags[n] & 2) != 0,
|
|
1051
|
-
g ? (a.xs.push(
|
|
967
|
+
var g = (a.flags[n] & 2) != 0, v = (a.flags[n] & 16) != 0;
|
|
968
|
+
g ? (a.xs.push(v ? r[s] : -r[s]), s++) : v ? a.xs.push(0) : (a.xs.push(t.readShort(r, s)), s += 2);
|
|
1052
969
|
}
|
|
1053
970
|
a.ys = [];
|
|
1054
971
|
for (var n = 0; n < c; n++) {
|
|
1055
|
-
var g = (a.flags[n] & 4) != 0,
|
|
1056
|
-
g ? (a.ys.push(
|
|
972
|
+
var g = (a.flags[n] & 4) != 0, v = (a.flags[n] & 32) != 0;
|
|
973
|
+
g ? (a.ys.push(v ? r[s] : -r[s]), s++) : v ? a.ys.push(0) : (a.ys.push(t.readShort(r, s)), s += 2);
|
|
1057
974
|
}
|
|
1058
975
|
for (var p = 0, b = 0, n = 0; n < c; n++)
|
|
1059
976
|
p += a.xs[n], b += a.ys[n], a.xs[n] = p, a.ys[n] = b;
|
|
@@ -1063,7 +980,7 @@ m.T.glyf = {
|
|
|
1063
980
|
}
|
|
1064
981
|
};
|
|
1065
982
|
typeof module < "u" && module.exports ? module.exports = m : typeof window < "u" && (window.Typr = m);
|
|
1066
|
-
class
|
|
983
|
+
class oe {
|
|
1067
984
|
/**
|
|
1068
985
|
* Extracts all available characters from a font's cmap tables.
|
|
1069
986
|
* @param font The parsed font object from Typr
|
|
@@ -1160,7 +1077,7 @@ class me {
|
|
|
1160
1077
|
return !(t >= 0 && t <= 31 && t !== 9 && t !== 10 && t !== 13 || t >= 127 && t <= 159);
|
|
1161
1078
|
}
|
|
1162
1079
|
}
|
|
1163
|
-
class
|
|
1080
|
+
class he {
|
|
1164
1081
|
/**
|
|
1165
1082
|
* Creates a new TextureAtlasCreation instance.
|
|
1166
1083
|
* @param renderer The WebGL renderer instance
|
|
@@ -1229,7 +1146,7 @@ class ge {
|
|
|
1229
1146
|
this._textureContext.putImageData(t, 0, 0);
|
|
1230
1147
|
}
|
|
1231
1148
|
}
|
|
1232
|
-
class
|
|
1149
|
+
class le {
|
|
1233
1150
|
/**
|
|
1234
1151
|
* Creates a new MetricsCalculation instance.
|
|
1235
1152
|
*/
|
|
@@ -1259,7 +1176,7 @@ class pe {
|
|
|
1259
1176
|
};
|
|
1260
1177
|
}
|
|
1261
1178
|
}
|
|
1262
|
-
class
|
|
1179
|
+
class ce {
|
|
1263
1180
|
/**
|
|
1264
1181
|
* Creates TextmodeCharacter objects with unique color assignments.
|
|
1265
1182
|
* @param characters Array of character strings
|
|
@@ -1326,7 +1243,7 @@ class _e {
|
|
|
1326
1243
|
* @returns RGB color as a tuple [r, g, b], or [0, 0, 0] if not found
|
|
1327
1244
|
*/
|
|
1328
1245
|
getCharacterColor(e, t) {
|
|
1329
|
-
if (!
|
|
1246
|
+
if (!_.validate(
|
|
1330
1247
|
typeof e == "string" && e.length === 1,
|
|
1331
1248
|
"Character must be a single character string.",
|
|
1332
1249
|
{ method: "getCharacterColor", providedValue: e }
|
|
@@ -1342,14 +1259,14 @@ class _e {
|
|
|
1342
1259
|
* @returns Array of RGB colors for each character
|
|
1343
1260
|
*/
|
|
1344
1261
|
getCharacterColors(e, t) {
|
|
1345
|
-
return
|
|
1262
|
+
return _.validate(
|
|
1346
1263
|
typeof e == "string" && e.length > 0,
|
|
1347
1264
|
"Characters must be a string with at least one character.",
|
|
1348
1265
|
{ method: "getCharacterColors", providedValue: e }
|
|
1349
1266
|
) ? e.split("").map((r) => this.getCharacterColor(r, t) || [0, 0, 0]) : [[0, 0, 0]];
|
|
1350
1267
|
}
|
|
1351
1268
|
}
|
|
1352
|
-
class
|
|
1269
|
+
class ue {
|
|
1353
1270
|
/**
|
|
1354
1271
|
* Creates a new TextmodeFont instance.
|
|
1355
1272
|
* @param renderer Renderer instance for texture creation
|
|
@@ -1371,7 +1288,7 @@ class ve {
|
|
|
1371
1288
|
o(this, "_textureAtlas");
|
|
1372
1289
|
o(this, "_metricsCalculator");
|
|
1373
1290
|
o(this, "_characterColorMapper");
|
|
1374
|
-
this._fontSize = t, this._characterExtractor = new
|
|
1291
|
+
this._fontSize = t, this._characterExtractor = new oe(), this._textureAtlas = new he(e), this._metricsCalculator = new le(), this._characterColorMapper = new ce();
|
|
1375
1292
|
}
|
|
1376
1293
|
/**
|
|
1377
1294
|
* Initializes the font manager by loading the font and creating the texture atlas.
|
|
@@ -1384,10 +1301,10 @@ class ve {
|
|
|
1384
1301
|
if (e) {
|
|
1385
1302
|
const r = await fetch(e);
|
|
1386
1303
|
if (!r.ok)
|
|
1387
|
-
throw new
|
|
1304
|
+
throw new x(`Failed to load font file: ${r.status} ${r.statusText}`);
|
|
1388
1305
|
t = await r.arrayBuffer();
|
|
1389
1306
|
} else
|
|
1390
|
-
throw new
|
|
1307
|
+
throw new x("Embedded font not available. This appears to be a minified build - please provide `fontSource`.");
|
|
1391
1308
|
await this._loadFontFace(t), this._font = m.parse(t)[0], await this._initializeFont();
|
|
1392
1309
|
}
|
|
1393
1310
|
/**
|
|
@@ -1420,7 +1337,7 @@ class ve {
|
|
|
1420
1337
|
try {
|
|
1421
1338
|
const t = await fetch(e);
|
|
1422
1339
|
if (!t.ok)
|
|
1423
|
-
throw new
|
|
1340
|
+
throw new x(`Failed to load font file: ${t.status} ${t.statusText}`);
|
|
1424
1341
|
const r = await t.arrayBuffer();
|
|
1425
1342
|
await this._loadFontFace(r);
|
|
1426
1343
|
const i = m.parse(r);
|
|
@@ -1428,7 +1345,7 @@ class ve {
|
|
|
1428
1345
|
throw new Error("Failed to parse font file");
|
|
1429
1346
|
this._font = i[0], await this._initializeFont();
|
|
1430
1347
|
} catch (t) {
|
|
1431
|
-
throw new
|
|
1348
|
+
throw new x(`Failed to load font: ${t instanceof Error ? t.message : "Unknown error"}`, t);
|
|
1432
1349
|
}
|
|
1433
1350
|
}
|
|
1434
1351
|
/**
|
|
@@ -1525,7 +1442,7 @@ class ve {
|
|
|
1525
1442
|
return this._font;
|
|
1526
1443
|
}
|
|
1527
1444
|
}
|
|
1528
|
-
class
|
|
1445
|
+
class de {
|
|
1529
1446
|
/**
|
|
1530
1447
|
* Create a new grid instance.
|
|
1531
1448
|
* @param canvas The canvas element used to determine the grid dimensions.
|
|
@@ -1660,7 +1577,7 @@ class xe {
|
|
|
1660
1577
|
return this._offsetY;
|
|
1661
1578
|
}
|
|
1662
1579
|
}
|
|
1663
|
-
class
|
|
1580
|
+
class fe {
|
|
1664
1581
|
constructor(e, t = !1, r = {}) {
|
|
1665
1582
|
o(this, "_canvas");
|
|
1666
1583
|
o(this, "captureSource");
|
|
@@ -1724,7 +1641,7 @@ class be {
|
|
|
1724
1641
|
powerPreference: "high-performance"
|
|
1725
1642
|
}, t = this._canvas.getContext("webgl2", e) || this._canvas.getContext("webgl", e);
|
|
1726
1643
|
if (!t)
|
|
1727
|
-
throw new
|
|
1644
|
+
throw new x("WebGL context could not be created. Ensure your browser supports WebGL.");
|
|
1728
1645
|
return t;
|
|
1729
1646
|
}
|
|
1730
1647
|
/**
|
|
@@ -1777,7 +1694,7 @@ class be {
|
|
|
1777
1694
|
return this._canvas.height;
|
|
1778
1695
|
}
|
|
1779
1696
|
}
|
|
1780
|
-
class
|
|
1697
|
+
class D {
|
|
1781
1698
|
/**
|
|
1782
1699
|
* Creates a new TextmodeConverter instance.
|
|
1783
1700
|
* @param renderer Renderer instance for texture creation
|
|
@@ -1856,7 +1773,7 @@ class U {
|
|
|
1856
1773
|
return this._options;
|
|
1857
1774
|
}
|
|
1858
1775
|
}
|
|
1859
|
-
class
|
|
1776
|
+
class me {
|
|
1860
1777
|
/**
|
|
1861
1778
|
* Create a new color palette instance.
|
|
1862
1779
|
* @param renderer The renderer instance.
|
|
@@ -1911,18 +1828,18 @@ class Ce {
|
|
|
1911
1828
|
return this._framebuffer.texture;
|
|
1912
1829
|
}
|
|
1913
1830
|
}
|
|
1914
|
-
class
|
|
1831
|
+
class N extends D {
|
|
1915
1832
|
constructor(t, r, i, s = {}) {
|
|
1916
1833
|
super(t, r, i, s);
|
|
1917
1834
|
o(this, "palette");
|
|
1918
|
-
this.palette = new
|
|
1835
|
+
this.palette = new me(this.renderer, this.fontManager.getCharacterColors(" .:-=+*%@#"));
|
|
1919
1836
|
}
|
|
1920
1837
|
/**
|
|
1921
1838
|
* Sets the characters used for mapping.
|
|
1922
1839
|
* @param characters The characters to use for mapping, usually ordered from darkest to brightest.
|
|
1923
1840
|
*/
|
|
1924
1841
|
characters(t) {
|
|
1925
|
-
|
|
1842
|
+
_.validate(
|
|
1926
1843
|
this.fontManager.hasAllCharacters(t),
|
|
1927
1844
|
"One or more characters do not exist in the current font.",
|
|
1928
1845
|
{ method: "characters", providedValue: t }
|
|
@@ -1941,7 +1858,7 @@ class O extends U {
|
|
|
1941
1858
|
if (typeof t == "string") {
|
|
1942
1859
|
const u = this.parseHexColor(t);
|
|
1943
1860
|
if (!u) {
|
|
1944
|
-
|
|
1861
|
+
_.validate(
|
|
1945
1862
|
!1,
|
|
1946
1863
|
"Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
|
|
1947
1864
|
{ method: "characterColor", providedValue: t }
|
|
@@ -1949,7 +1866,7 @@ class O extends U {
|
|
|
1949
1866
|
return;
|
|
1950
1867
|
}
|
|
1951
1868
|
[a, n, l, c] = u;
|
|
1952
|
-
} else if (a = t, n = r !== void 0 ? r : t, l = i !== void 0 ? i : t, c = s, !
|
|
1869
|
+
} else if (a = t, n = r !== void 0 ? r : t, l = i !== void 0 ? i : t, c = s, !_.validate(
|
|
1953
1870
|
[a, n, l, c].every((u) => u >= 0 && u <= 255),
|
|
1954
1871
|
"Character color values must be between 0 and 255",
|
|
1955
1872
|
{ method: "characterColor", providedValues: { r: a, g: n, b: l, a: c } }
|
|
@@ -1964,7 +1881,7 @@ class O extends U {
|
|
|
1964
1881
|
* @param mode The color mode to use for characters.
|
|
1965
1882
|
*/
|
|
1966
1883
|
characterColorMode(t) {
|
|
1967
|
-
|
|
1884
|
+
_.validate(
|
|
1968
1885
|
["sampled", "fixed"].includes(t),
|
|
1969
1886
|
"Invalid character color mode. Must be 'sampled' or 'fixed'.",
|
|
1970
1887
|
{ method: "characterColorMode", providedValue: t }
|
|
@@ -1983,7 +1900,7 @@ class O extends U {
|
|
|
1983
1900
|
if (typeof t == "string") {
|
|
1984
1901
|
const u = this.parseHexColor(t);
|
|
1985
1902
|
if (!u) {
|
|
1986
|
-
|
|
1903
|
+
_.validate(
|
|
1987
1904
|
!1,
|
|
1988
1905
|
"Invalid hex color format. Use '#FF0000', '#F00', 'FF0000', or 'F00'.",
|
|
1989
1906
|
{ method: "cellColor", providedValue: t }
|
|
@@ -1991,7 +1908,7 @@ class O extends U {
|
|
|
1991
1908
|
return;
|
|
1992
1909
|
}
|
|
1993
1910
|
[a, n, l, c] = u;
|
|
1994
|
-
} else if (a = t, n = r !== void 0 ? r : t, l = i !== void 0 ? i : t, c = s, !
|
|
1911
|
+
} else if (a = t, n = r !== void 0 ? r : t, l = i !== void 0 ? i : t, c = s, !_.validate(
|
|
1995
1912
|
[a, n, l, c].every((u) => u >= 0 && u <= 255),
|
|
1996
1913
|
"Cell color values must be between 0 and 255",
|
|
1997
1914
|
{ method: "cellColor", providedValues: { r: a, g: n, b: l, a: c } }
|
|
@@ -2006,7 +1923,7 @@ class O extends U {
|
|
|
2006
1923
|
* @param mode The color mode to use for background cells.
|
|
2007
1924
|
*/
|
|
2008
1925
|
cellColorMode(t) {
|
|
2009
|
-
|
|
1926
|
+
_.validate(
|
|
2010
1927
|
["sampled", "fixed"].includes(t),
|
|
2011
1928
|
"Invalid cell color mode. Must be 'sampled' or 'fixed'.",
|
|
2012
1929
|
{ method: "cellColorMode", providedValue: t }
|
|
@@ -2017,7 +1934,7 @@ class O extends U {
|
|
|
2017
1934
|
* @param invert If `true`, the character color becomes the cell color and vice versa.
|
|
2018
1935
|
*/
|
|
2019
1936
|
invert(t) {
|
|
2020
|
-
|
|
1937
|
+
_.validate(
|
|
2021
1938
|
typeof t == "boolean" || typeof t == "number" && Number.isInteger(t),
|
|
2022
1939
|
"Invert must be a boolean value or an integer (0 for false, any other number for true).",
|
|
2023
1940
|
{ method: "invert", providedValue: t }
|
|
@@ -2028,7 +1945,7 @@ class O extends U {
|
|
|
2028
1945
|
* @param angle The rotation angle in degrees.
|
|
2029
1946
|
*/
|
|
2030
1947
|
rotation(t) {
|
|
2031
|
-
if (!
|
|
1948
|
+
if (!_.validate(
|
|
2032
1949
|
typeof t == "number",
|
|
2033
1950
|
"Rotation angle must be a number.",
|
|
2034
1951
|
{ method: "rotation", providedValue: t }
|
|
@@ -2043,7 +1960,7 @@ class O extends U {
|
|
|
2043
1960
|
* @param flip If `true`, characters are flipped horizontally. If `false`, no flip is applied.
|
|
2044
1961
|
*/
|
|
2045
1962
|
flipHorizontally(t) {
|
|
2046
|
-
|
|
1963
|
+
_.validate(
|
|
2047
1964
|
typeof t == "boolean" || typeof t == "number" && Number.isInteger(t),
|
|
2048
1965
|
"Flip horizontally must be a boolean value or an integer (0 for false, any other number for true).",
|
|
2049
1966
|
{ method: "flipHorizontally", providedValue: t }
|
|
@@ -2054,7 +1971,7 @@ class O extends U {
|
|
|
2054
1971
|
* @param flip If `true`, characters are flipped vertically. If `false`, no flip is applied.
|
|
2055
1972
|
*/
|
|
2056
1973
|
flipVertically(t) {
|
|
2057
|
-
|
|
1974
|
+
_.validate(
|
|
2058
1975
|
typeof t == "boolean" || typeof t == "number" && Number.isInteger(t),
|
|
2059
1976
|
"Flip vertically must be a boolean value or an integer (0 for false, any other number for true).",
|
|
2060
1977
|
{ method: "flipVertically", providedValue: t }
|
|
@@ -2073,8 +1990,8 @@ class O extends U {
|
|
|
2073
1990
|
return [r, i, s, 255];
|
|
2074
1991
|
}
|
|
2075
1992
|
}
|
|
2076
|
-
var
|
|
2077
|
-
const
|
|
1993
|
+
var ge = "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);}}", pe = "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);}}", _e = "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);}}", ve = "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);}}", be = "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);}";
|
|
1994
|
+
const xe = {
|
|
2078
1995
|
/** Enable/disable the renderer */
|
|
2079
1996
|
enabled: !0,
|
|
2080
1997
|
/** Characters used for brightness mapping (from darkest to brightest) */
|
|
@@ -2100,7 +2017,7 @@ const Re = {
|
|
|
2100
2017
|
/** Range of brightness values to map to ASCII characters */
|
|
2101
2018
|
brightnessRange: [0, 255]
|
|
2102
2019
|
};
|
|
2103
|
-
class L extends
|
|
2020
|
+
class L extends N {
|
|
2104
2021
|
/**
|
|
2105
2022
|
* Creates a new TextmodeBrightnessConverter instance.
|
|
2106
2023
|
* @param renderer Renderer instance for texture creation
|
|
@@ -2109,14 +2026,14 @@ class L extends O {
|
|
|
2109
2026
|
* @ignore
|
|
2110
2027
|
*/
|
|
2111
2028
|
constructor(t, r, i) {
|
|
2112
|
-
super(t, r, i, { ...
|
|
2029
|
+
super(t, r, i, { ...xe });
|
|
2113
2030
|
o(this, "sampleShader");
|
|
2114
2031
|
o(this, "colorFillShader");
|
|
2115
2032
|
o(this, "charMappingShader");
|
|
2116
2033
|
o(this, "transformFillShader");
|
|
2117
2034
|
o(this, "rotationFillShader");
|
|
2118
2035
|
o(this, "sampleFramebuffer");
|
|
2119
|
-
this.sampleShader = new y(t.context, T,
|
|
2036
|
+
this.sampleShader = new y(t.context, T, ge), this.colorFillShader = new y(t.context, T, pe), this.transformFillShader = new y(t.context, T, _e), this.rotationFillShader = new y(t.context, T, ve), this.charMappingShader = new y(t.context, T, be), this.sampleFramebuffer = this.renderer.createFramebuffer(this.grid.cols, this.grid.rows);
|
|
2120
2037
|
}
|
|
2121
2038
|
convert(t) {
|
|
2122
2039
|
this.sampleFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.sampleShader), this.renderer.setUniform("u_sketchTexture", t), this.renderer.setUniform("u_gridCellDimensions", [this.grid.cols, this.grid.rows]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this.sampleFramebuffer.end(), this._primaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.characterColor), this.renderer.setUniform("u_useFixedColor", this._options.characterColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._primaryColorFramebuffer.end(), this._secondaryColorFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.colorFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_fillColor", this._options.cellColor), this.renderer.setUniform("u_useFixedColor", this._options.cellColorMode === "fixed"), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._secondaryColorFramebuffer.end(), this._transformFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.transformFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_invert", this._options.invert), this.renderer.setUniform("u_flipHorizontally", this._options.flipHorizontally), this.renderer.setUniform("u_flipVertically", this._options.flipVertically), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._transformFramebuffer.end(), this._rotationFramebuffer.begin(), this.renderer.clear(), this.renderer.shader(this.rotationFillShader), this.renderer.setUniform("u_sampleTexture", this.sampleFramebuffer.texture), this.renderer.setUniform("u_rotationColor", this._options.rotation), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._rotationFramebuffer.end(), this._characterFramebuffer.begin(), this.renderer.clear(0, 0, 0, 0), this.renderer.shader(this.charMappingShader), this.renderer.setUniform("u_colorSampleFramebuffer", this.sampleFramebuffer.texture), this.renderer.setUniform("u_charPaletteTexture", this.palette.texture), this.renderer.setUniform("u_charPaletteSize", [this.palette.colors.length, 1]), this.renderer.setUniform("u_brightnessRange", this._options.brightnessRange), this.renderer.rect(0, 0, this.grid.cols, this.grid.rows), this._characterFramebuffer.end();
|
|
@@ -2132,21 +2049,21 @@ class L extends O {
|
|
|
2132
2049
|
* @param range Array of two numbers `[min, max]`, where `min` is darkest and `max` is brightest.
|
|
2133
2050
|
*/
|
|
2134
2051
|
brightnessRange(t) {
|
|
2135
|
-
|
|
2052
|
+
_.validate(
|
|
2136
2053
|
Array.isArray(t) && t.length === 2 && t.every((r) => typeof r == "number" && r >= 0 && r <= 255),
|
|
2137
2054
|
"Brightness range must be an array of two numbers between 0 and 255.",
|
|
2138
2055
|
{ method: "brightnessRange", providedValue: t }
|
|
2139
2056
|
) && (this._options.brightnessRange = t);
|
|
2140
2057
|
}
|
|
2141
2058
|
}
|
|
2142
|
-
const
|
|
2059
|
+
const Pe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
2143
2060
|
__proto__: null,
|
|
2144
2061
|
TextmodeBrightnessConverter: L,
|
|
2145
|
-
TextmodeConverter:
|
|
2146
|
-
TextmodeFeatureConverter:
|
|
2062
|
+
TextmodeConverter: D,
|
|
2063
|
+
TextmodeFeatureConverter: N
|
|
2147
2064
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
2148
|
-
var
|
|
2149
|
-
class
|
|
2065
|
+
var Ce = "precision mediump float;uniform sampler2D u_characterTexture;uniform vec2 u_charsetDimensions;uniform sampler2D u_primaryColorTexture;uniform sampler2D u_secondaryColorTexture;uniform sampler2D u_transformTexture;uniform sampler2D u_asciiCharacterTexture;uniform sampler2D u_rotationTexture;uniform sampler2D u_captureTexture;uniform vec2 u_captureDimensions;uniform int u_backgroundMode;uniform vec2 u_gridCellDimensions;uniform vec2 u_gridPixelDimensions;mat2 rotate2D(float angle){float s=sin(angle);float c=cos(angle);return mat2(c,-s,s,c);}void main(){vec2 adjustedCoord=gl_FragCoord.xy/u_gridPixelDimensions;vec2 gridCoord=adjustedCoord*u_gridCellDimensions;vec2 cellCoord=floor(gridCoord);vec2 charIndexTexCoord=(cellCoord+0.5)/u_gridCellDimensions;vec4 primaryColor=texture2D(u_primaryColorTexture,charIndexTexCoord);vec4 secondaryColor=texture2D(u_secondaryColorTexture,charIndexTexCoord);vec4 transformColor=texture2D(u_transformTexture,charIndexTexCoord);bool isInverted=transformColor.r>0.5;bool flipHorizontal=transformColor.g>0.5;bool flipVertical=transformColor.b>0.5;vec4 encodedIndexVec=texture2D(u_asciiCharacterTexture,charIndexTexCoord);if(encodedIndexVec.a<0.01){gl_FragColor=(u_backgroundMode==0)? vec4(0.0):texture2D(u_captureTexture,gl_FragCoord.xy/u_captureDimensions);return;}int charIndex=int(encodedIndexVec.r*255.0+0.5)+int(encodedIndexVec.g*255.0+0.5)*256;int charCol=int(mod(float(charIndex),u_charsetDimensions.x));int charRow=charIndex/int(u_charsetDimensions.x);float flippedRow=(u_charsetDimensions.y-1.0)-float(charRow);vec2 charCoord=vec2(float(charCol),flippedRow)/u_charsetDimensions;vec4 rotationColor=texture2D(u_rotationTexture,charIndexTexCoord);float scaledAngle=rotationColor.r*255.0+rotationColor.g;float rotationAngle=(scaledAngle*360.0/255.0)*0.017453292;vec2 fractionalPart=fract(gridCoord)-0.5;if(flipHorizontal)fractionalPart.x=-fractionalPart.x;if(flipVertical)fractionalPart.y=-fractionalPart.y;fractionalPart=rotate2D(rotationAngle)*fractionalPart+0.5;vec2 cellSize=1.0/u_charsetDimensions;vec2 texCoord=charCoord+fractionalPart*cellSize;vec2 cellMax=charCoord+cellSize;if(any(lessThan(texCoord,charCoord))||any(greaterThan(texCoord,cellMax))){gl_FragColor=isInverted ? primaryColor : secondaryColor;return;}vec4 charTexel=texture2D(u_characterTexture,texCoord);if(isInverted)charTexel.rgb=1.0-charTexel.rgb;gl_FragColor=mix(secondaryColor,primaryColor,charTexel);}";
|
|
2066
|
+
class Fe {
|
|
2150
2067
|
/**
|
|
2151
2068
|
* Creates an instance of TextmodeConversionPipeline.
|
|
2152
2069
|
* @param renderer The renderer to use for the pipeline.
|
|
@@ -2166,9 +2083,9 @@ class Ue {
|
|
|
2166
2083
|
o(this, "_secondaryColorFramebuffer");
|
|
2167
2084
|
o(this, "_rotationFramebuffer");
|
|
2168
2085
|
o(this, "_transformFramebuffer");
|
|
2169
|
-
this.renderer = e, this.font = t, this.grid = r, this._asciiShader = this.renderer.createShader(T,
|
|
2086
|
+
this.renderer = e, this.font = t, this.grid = r, this._asciiShader = this.renderer.createShader(T, Ce), this.converters = [
|
|
2170
2087
|
{ name: "brightness", converter: new L(e, t, r) },
|
|
2171
|
-
{ name: "custom", converter: new
|
|
2088
|
+
{ name: "custom", converter: new D(e, t, r) }
|
|
2172
2089
|
], this._characterFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._primaryColorFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._secondaryColorFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._rotationFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._transformFramebuffer = this.renderer.createFramebuffer(r.cols, r.rows), this._resultFramebuffer = this.renderer.createFramebuffer(this.grid.width, this.grid.height);
|
|
2173
2090
|
}
|
|
2174
2091
|
/**
|
|
@@ -2179,7 +2096,7 @@ class Ue {
|
|
|
2179
2096
|
render(e) {
|
|
2180
2097
|
for (const r of this.converters) {
|
|
2181
2098
|
const i = r.converter;
|
|
2182
|
-
i.options.enabled && i instanceof
|
|
2099
|
+
i.options.enabled && i instanceof N && i.convert(e);
|
|
2183
2100
|
}
|
|
2184
2101
|
const t = (r, i) => {
|
|
2185
2102
|
r.begin(), this.renderer.clear();
|
|
@@ -2197,15 +2114,15 @@ class Ue {
|
|
|
2197
2114
|
* @returns The requested `TextmodeConverter` instance.
|
|
2198
2115
|
*/
|
|
2199
2116
|
get(e) {
|
|
2200
|
-
if (!
|
|
2117
|
+
if (!_.validate(
|
|
2201
2118
|
typeof e == "string" && e.length > 0,
|
|
2202
2119
|
"Converter name must be a non-empty string.",
|
|
2203
2120
|
{ method: "converter", providedValue: e }
|
|
2204
2121
|
))
|
|
2205
2122
|
return;
|
|
2206
2123
|
const t = this.converters.find((i) => i.name === e), r = t == null ? void 0 : t.converter;
|
|
2207
|
-
if (
|
|
2208
|
-
r instanceof
|
|
2124
|
+
if (_.validate(
|
|
2125
|
+
r instanceof D,
|
|
2209
2126
|
`Converter "${e}" is not a valid TextmodeConverter.`,
|
|
2210
2127
|
{ method: "converter", providedValue: e, converterInstance: r }
|
|
2211
2128
|
))
|
|
@@ -2218,33 +2135,33 @@ class Ue {
|
|
|
2218
2135
|
* @returns The newly created {@link TextmodeConverter} instance or `void` if the addition failed.
|
|
2219
2136
|
*/
|
|
2220
2137
|
add(e, t) {
|
|
2221
|
-
if (!
|
|
2138
|
+
if (!_.validate(
|
|
2222
2139
|
typeof e == "string" && e.length > 0,
|
|
2223
2140
|
"Converter name must be a non-empty string.",
|
|
2224
2141
|
{ method: "add", providedValue: e }
|
|
2225
|
-
) || !
|
|
2142
|
+
) || !_.validate(
|
|
2226
2143
|
t === "brightness" || t === "custom",
|
|
2227
2144
|
`Converter type must be either "brightness" or "custom". Provided: ${t}`,
|
|
2228
2145
|
{ method: "add", providedValue: t }
|
|
2229
2146
|
))
|
|
2230
2147
|
return;
|
|
2231
2148
|
let r;
|
|
2232
|
-
return t === "brightness" ? r = new L(this.renderer, this.font, this.grid) : r = new
|
|
2149
|
+
return t === "brightness" ? r = new L(this.renderer, this.font, this.grid) : r = new D(this.renderer, this.font, this.grid), this.converters.push({ name: e, converter: r }), r;
|
|
2233
2150
|
}
|
|
2234
2151
|
/**
|
|
2235
2152
|
* Removes a converter from the pipeline by name or instance.
|
|
2236
2153
|
* @param nameOrInstance The unique name of the converter or the converter instance to remove.
|
|
2237
2154
|
*/
|
|
2238
2155
|
remove(e) {
|
|
2239
|
-
if (!
|
|
2240
|
-
typeof e == "string" || e instanceof
|
|
2156
|
+
if (!_.validate(
|
|
2157
|
+
typeof e == "string" || e instanceof D,
|
|
2241
2158
|
"Parameter must be either a string (converter name) or a TextmodeConverter instance.",
|
|
2242
2159
|
{ method: "remove", providedValue: e }
|
|
2243
2160
|
))
|
|
2244
2161
|
return;
|
|
2245
2162
|
let t = -1;
|
|
2246
2163
|
if (typeof e == "string") {
|
|
2247
|
-
if (!
|
|
2164
|
+
if (!_.validate(
|
|
2248
2165
|
e.length > 0,
|
|
2249
2166
|
"Converter name must be a non-empty string.",
|
|
2250
2167
|
{ method: "remove", providedValue: e }
|
|
@@ -2253,7 +2170,7 @@ class Ue {
|
|
|
2253
2170
|
t = this.converters.findIndex((r) => r.name === e);
|
|
2254
2171
|
} else
|
|
2255
2172
|
t = this.converters.findIndex((r) => r.converter === e);
|
|
2256
|
-
|
|
2173
|
+
_.validate(
|
|
2257
2174
|
t !== -1,
|
|
2258
2175
|
typeof e == "string" ? `Converter with name "${e}" not found in pipeline.` : "Converter instance not found in pipeline.",
|
|
2259
2176
|
{ method: "remove", providedValue: e, convertersCount: this.converters.length }
|
|
@@ -2424,7 +2341,7 @@ class X {
|
|
|
2424
2341
|
return `'textmode-export'-${this.generateTimestamp()}`;
|
|
2425
2342
|
}
|
|
2426
2343
|
}
|
|
2427
|
-
class
|
|
2344
|
+
class we extends H {
|
|
2428
2345
|
/**
|
|
2429
2346
|
* Extracts transform data from transform pixels
|
|
2430
2347
|
* @param transformPixels Transform framebuffer pixels
|
|
@@ -2494,7 +2411,7 @@ class Ae extends H {
|
|
|
2494
2411
|
return r;
|
|
2495
2412
|
}
|
|
2496
2413
|
}
|
|
2497
|
-
class
|
|
2414
|
+
class ye {
|
|
2498
2415
|
/**
|
|
2499
2416
|
* Gets the glyph index for a given Unicode code point in a Typr.js font
|
|
2500
2417
|
* @param fontData The Typr.js font data
|
|
@@ -2572,22 +2489,22 @@ class Me {
|
|
|
2572
2489
|
const f = n[d];
|
|
2573
2490
|
if (!(f < u)) {
|
|
2574
2491
|
if (f >= u) {
|
|
2575
|
-
const g = t + s[u] * i,
|
|
2576
|
-
c += `M${g.toFixed(2)},${
|
|
2492
|
+
const g = t + s[u] * i, v = r - a[u] * i;
|
|
2493
|
+
c += `M${g.toFixed(2)},${v.toFixed(2)}`;
|
|
2577
2494
|
let p = u + 1;
|
|
2578
2495
|
for (; p <= f; )
|
|
2579
2496
|
if ((l[p] & 1) !== 0) {
|
|
2580
|
-
const
|
|
2581
|
-
c += `L${
|
|
2497
|
+
const w = t + s[p] * i, F = r - a[p] * i;
|
|
2498
|
+
c += `L${w.toFixed(2)},${F.toFixed(2)}`, p++;
|
|
2582
2499
|
} else {
|
|
2583
|
-
const
|
|
2584
|
-
let
|
|
2585
|
-
if ((l[
|
|
2586
|
-
const
|
|
2587
|
-
c += `Q${
|
|
2500
|
+
const w = t + s[p] * i, F = r - a[p] * i;
|
|
2501
|
+
let C = p + 1 > f ? u : p + 1;
|
|
2502
|
+
if ((l[C] & 1) !== 0) {
|
|
2503
|
+
const U = t + s[C] * i, S = r - a[C] * i;
|
|
2504
|
+
c += `Q${w.toFixed(2)},${F.toFixed(2)} ${U.toFixed(2)},${S.toFixed(2)}`, p = C + 1;
|
|
2588
2505
|
} else {
|
|
2589
|
-
const
|
|
2590
|
-
c += `Q${
|
|
2506
|
+
const U = t + s[C] * i, S = r - a[C] * i, R = (w + U) / 2, E = (F + S) / 2;
|
|
2507
|
+
c += `Q${w.toFixed(2)},${F.toFixed(2)} ${R.toFixed(2)},${E.toFixed(2)}`, p = C;
|
|
2591
2508
|
}
|
|
2592
2509
|
}
|
|
2593
2510
|
c += "Z";
|
|
@@ -2643,10 +2560,10 @@ class Me {
|
|
|
2643
2560
|
}
|
|
2644
2561
|
}
|
|
2645
2562
|
}
|
|
2646
|
-
class
|
|
2563
|
+
class Te {
|
|
2647
2564
|
constructor() {
|
|
2648
2565
|
o(this, "pathGenerator");
|
|
2649
|
-
this.pathGenerator = new
|
|
2566
|
+
this.pathGenerator = new ye();
|
|
2650
2567
|
}
|
|
2651
2568
|
/**
|
|
2652
2569
|
* Generates the SVG header with metadata
|
|
@@ -2791,7 +2708,7 @@ class De {
|
|
|
2791
2708
|
`).replace(/[ \t]+$/gm, "");
|
|
2792
2709
|
}
|
|
2793
2710
|
}
|
|
2794
|
-
class
|
|
2711
|
+
class Se extends X {
|
|
2795
2712
|
/**
|
|
2796
2713
|
* Creates a downloadable blob from SVG content
|
|
2797
2714
|
* @param svgContent The SVG content string
|
|
@@ -2821,12 +2738,12 @@ class Ie extends X {
|
|
|
2821
2738
|
this.downloadSVG(e, t || this.generateDefaultFilename());
|
|
2822
2739
|
}
|
|
2823
2740
|
}
|
|
2824
|
-
class
|
|
2741
|
+
class q {
|
|
2825
2742
|
constructor() {
|
|
2826
2743
|
o(this, "dataExtractor");
|
|
2827
2744
|
o(this, "contentGenerator");
|
|
2828
2745
|
o(this, "fileHandler");
|
|
2829
|
-
this.dataExtractor = new
|
|
2746
|
+
this.dataExtractor = new we(), this.contentGenerator = new Te(), this.fileHandler = new Se();
|
|
2830
2747
|
}
|
|
2831
2748
|
/**
|
|
2832
2749
|
* Applies default values to SVG export options
|
|
@@ -2873,7 +2790,7 @@ class Y {
|
|
|
2873
2790
|
}
|
|
2874
2791
|
}
|
|
2875
2792
|
}
|
|
2876
|
-
class
|
|
2793
|
+
class Re extends H {
|
|
2877
2794
|
/**
|
|
2878
2795
|
* Extracts character data for TXT generation
|
|
2879
2796
|
* @param framebufferData Framebuffer pixel data
|
|
@@ -2900,7 +2817,7 @@ class Pe extends H {
|
|
|
2900
2817
|
return s;
|
|
2901
2818
|
}
|
|
2902
2819
|
}
|
|
2903
|
-
class
|
|
2820
|
+
class Ee {
|
|
2904
2821
|
/**
|
|
2905
2822
|
* Generates TXT content from a 2D character array
|
|
2906
2823
|
* @param characterGrid 2D array of characters (rows x columns)
|
|
@@ -2919,7 +2836,7 @@ class Be {
|
|
|
2919
2836
|
return r.join(i);
|
|
2920
2837
|
}
|
|
2921
2838
|
}
|
|
2922
|
-
class
|
|
2839
|
+
class Ue extends X {
|
|
2923
2840
|
/**
|
|
2924
2841
|
* Saves TXT content as a downloadable file
|
|
2925
2842
|
* @param content The TXT content to save
|
|
@@ -2943,12 +2860,12 @@ class Ge extends X {
|
|
|
2943
2860
|
return t === ".txt" || t.length <= 4 ? this.generateDefaultFilename() : t;
|
|
2944
2861
|
}
|
|
2945
2862
|
}
|
|
2946
|
-
class
|
|
2863
|
+
class K {
|
|
2947
2864
|
constructor() {
|
|
2948
2865
|
o(this, "dataExtractor");
|
|
2949
2866
|
o(this, "contentGenerator");
|
|
2950
2867
|
o(this, "fileHandler");
|
|
2951
|
-
this.dataExtractor = new
|
|
2868
|
+
this.dataExtractor = new Re(), this.contentGenerator = new Ee(), this.fileHandler = new Ue();
|
|
2952
2869
|
}
|
|
2953
2870
|
/**
|
|
2954
2871
|
* Applies default values to TXT export options
|
|
@@ -2994,7 +2911,7 @@ class j {
|
|
|
2994
2911
|
}
|
|
2995
2912
|
}
|
|
2996
2913
|
}
|
|
2997
|
-
class
|
|
2914
|
+
class Me extends H {
|
|
2998
2915
|
/**
|
|
2999
2916
|
* Captures the current state of the textmode canvas as image data
|
|
3000
2917
|
* @param canvas The canvas data containing the rendered textmode graphics
|
|
@@ -3020,7 +2937,7 @@ class Ve extends H {
|
|
|
3020
2937
|
), s;
|
|
3021
2938
|
}
|
|
3022
2939
|
}
|
|
3023
|
-
class
|
|
2940
|
+
class Ae {
|
|
3024
2941
|
/**
|
|
3025
2942
|
* Generates image data from canvas
|
|
3026
2943
|
* @param canvas The canvas containing the image data
|
|
@@ -3063,16 +2980,16 @@ class ke {
|
|
|
3063
2980
|
}
|
|
3064
2981
|
}
|
|
3065
2982
|
}
|
|
3066
|
-
const
|
|
2983
|
+
const Q = {
|
|
3067
2984
|
png: "image/png",
|
|
3068
2985
|
jpg: "image/jpeg",
|
|
3069
2986
|
webp: "image/webp"
|
|
3070
|
-
},
|
|
2987
|
+
}, V = {
|
|
3071
2988
|
png: ".png",
|
|
3072
2989
|
jpg: ".jpg",
|
|
3073
2990
|
webp: ".webp"
|
|
3074
2991
|
};
|
|
3075
|
-
class
|
|
2992
|
+
class De extends X {
|
|
3076
2993
|
/**
|
|
3077
2994
|
* Saves image content as a downloadable file
|
|
3078
2995
|
* @param content The image content (data URL or blob)
|
|
@@ -3081,7 +2998,7 @@ class ze extends X {
|
|
|
3081
2998
|
*/
|
|
3082
2999
|
saveImage(e, t, r) {
|
|
3083
3000
|
try {
|
|
3084
|
-
const i =
|
|
3001
|
+
const i = V[r];
|
|
3085
3002
|
typeof e == "string" ? this.saveImageFromDataURL(e, this.sanitizeFilename(t) + i) : this.saveImageFromBlob(e, this.sanitizeFilename(t) + i);
|
|
3086
3003
|
} catch (i) {
|
|
3087
3004
|
throw console.error(`Failed to save ${r.toUpperCase()} image:`, i), new Error(`Image save failed: ${i instanceof Error ? i.message : "Unknown error"}`);
|
|
@@ -3116,7 +3033,7 @@ class ze extends X {
|
|
|
3116
3033
|
* @returns True if the format is supported for saving
|
|
3117
3034
|
*/
|
|
3118
3035
|
validateSaveSupport(e) {
|
|
3119
|
-
return e in
|
|
3036
|
+
return e in Q && e in V;
|
|
3120
3037
|
}
|
|
3121
3038
|
/**
|
|
3122
3039
|
* Gets the MIME type for the specified image format
|
|
@@ -3124,7 +3041,7 @@ class ze extends X {
|
|
|
3124
3041
|
* @returns The MIME type string
|
|
3125
3042
|
*/
|
|
3126
3043
|
getMimeType(e) {
|
|
3127
|
-
return
|
|
3044
|
+
return Q[e];
|
|
3128
3045
|
}
|
|
3129
3046
|
/**
|
|
3130
3047
|
* Gets the file extension for the specified image format
|
|
@@ -3132,15 +3049,15 @@ class ze extends X {
|
|
|
3132
3049
|
* @returns The file extension (including the dot)
|
|
3133
3050
|
*/
|
|
3134
3051
|
getFileExtension(e) {
|
|
3135
|
-
return
|
|
3052
|
+
return V[e];
|
|
3136
3053
|
}
|
|
3137
3054
|
}
|
|
3138
|
-
class
|
|
3055
|
+
class Ie {
|
|
3139
3056
|
constructor() {
|
|
3140
3057
|
o(this, "dataExtractor");
|
|
3141
3058
|
o(this, "contentGenerator");
|
|
3142
3059
|
o(this, "fileHandler");
|
|
3143
|
-
this.dataExtractor = new
|
|
3060
|
+
this.dataExtractor = new Me(), this.contentGenerator = new Ae(), this.fileHandler = new De();
|
|
3144
3061
|
}
|
|
3145
3062
|
/**
|
|
3146
3063
|
* Applies default values to image export options
|
|
@@ -3223,7 +3140,7 @@ class $e {
|
|
|
3223
3140
|
}
|
|
3224
3141
|
}
|
|
3225
3142
|
}
|
|
3226
|
-
class
|
|
3143
|
+
class k {
|
|
3227
3144
|
constructor(e = null, t = {}) {
|
|
3228
3145
|
/** The element to capture content from (optional for standalone mode) */
|
|
3229
3146
|
o(this, "captureSource");
|
|
@@ -3267,12 +3184,12 @@ class I {
|
|
|
3267
3184
|
* @ignore
|
|
3268
3185
|
*/
|
|
3269
3186
|
static async create(e = null, t = {}) {
|
|
3270
|
-
const r = new
|
|
3271
|
-
r.textmodeCanvas = new
|
|
3187
|
+
const r = new k(e, t), i = r._standalone ? t : void 0;
|
|
3188
|
+
r.textmodeCanvas = new fe(r.captureSource, r._standalone, i), r._renderer = new ne(r.textmodeCanvas.getWebGLContext());
|
|
3272
3189
|
let s, a;
|
|
3273
|
-
r._standalone ? (s = t.width || 800, a = t.height || 600) : (s = r.textmodeCanvas.width || 800, a = r.textmodeCanvas.height || 600), r._canvasFramebuffer = r._renderer.createFramebuffer(s, a), r._font = new
|
|
3190
|
+
r._standalone ? (s = t.width || 800, a = t.height || 600) : (s = r.textmodeCanvas.width || 800, a = r.textmodeCanvas.height || 600), r._canvasFramebuffer = r._renderer.createFramebuffer(s, a), r._font = new ue(r._renderer, t.fontSize ?? 16), await r._font.initialize(t.fontSource);
|
|
3274
3191
|
const n = r._font.maxGlyphDimensions;
|
|
3275
|
-
return r._grid = new
|
|
3192
|
+
return r._grid = new de(r.textmodeCanvas.canvas, n.width, n.height), r._pipeline = new Fe(r._renderer, r._font, r._grid), r.setupEventListeners(), r.startAutoRendering(), r;
|
|
3276
3193
|
}
|
|
3277
3194
|
setupEventListeners() {
|
|
3278
3195
|
this._windowResizeListener = () => {
|
|
@@ -3320,7 +3237,7 @@ class I {
|
|
|
3320
3237
|
* ```
|
|
3321
3238
|
*/
|
|
3322
3239
|
toString(e = {}) {
|
|
3323
|
-
return new
|
|
3240
|
+
return new K().generateTXT(this, e);
|
|
3324
3241
|
}
|
|
3325
3242
|
/**
|
|
3326
3243
|
* Export the current textmode rendering to a TXT file.
|
|
@@ -3345,7 +3262,7 @@ class I {
|
|
|
3345
3262
|
* ```
|
|
3346
3263
|
*/
|
|
3347
3264
|
saveStrings(e = {}) {
|
|
3348
|
-
new
|
|
3265
|
+
new K().saveTXT(this, e);
|
|
3349
3266
|
}
|
|
3350
3267
|
/**
|
|
3351
3268
|
* Generate the current textmode rendering as an SVG string.
|
|
@@ -3374,7 +3291,7 @@ class I {
|
|
|
3374
3291
|
* ```
|
|
3375
3292
|
*/
|
|
3376
3293
|
toSVG(e = {}) {
|
|
3377
|
-
return new
|
|
3294
|
+
return new q().generateSVG(this, e);
|
|
3378
3295
|
}
|
|
3379
3296
|
/**
|
|
3380
3297
|
* Export the current textmode rendering to an SVG file.
|
|
@@ -3398,7 +3315,7 @@ class I {
|
|
|
3398
3315
|
* ```
|
|
3399
3316
|
*/
|
|
3400
3317
|
saveSVG(e = {}) {
|
|
3401
|
-
new
|
|
3318
|
+
new q().saveSVG(this, e);
|
|
3402
3319
|
}
|
|
3403
3320
|
/**
|
|
3404
3321
|
* Export the current textmode rendering to an image file.
|
|
@@ -3429,7 +3346,7 @@ class I {
|
|
|
3429
3346
|
* ```
|
|
3430
3347
|
*/
|
|
3431
3348
|
async saveCanvas(e, t = "png", r = {}) {
|
|
3432
|
-
await new
|
|
3349
|
+
await new Ie().saveImage(this.textmodeCanvas, {
|
|
3433
3350
|
...r,
|
|
3434
3351
|
filename: e,
|
|
3435
3352
|
format: t
|
|
@@ -3691,7 +3608,7 @@ class I {
|
|
|
3691
3608
|
* ```
|
|
3692
3609
|
*/
|
|
3693
3610
|
redraw(e = 1) {
|
|
3694
|
-
if (
|
|
3611
|
+
if (_.validate(
|
|
3695
3612
|
typeof e == "number" && e > 0 && Number.isInteger(e),
|
|
3696
3613
|
"Redraw count must be a positive integer.",
|
|
3697
3614
|
{ method: "redraw", providedValue: e }
|
|
@@ -3747,7 +3664,7 @@ class I {
|
|
|
3747
3664
|
* ```
|
|
3748
3665
|
*/
|
|
3749
3666
|
fontSize(e) {
|
|
3750
|
-
|
|
3667
|
+
_.validate(
|
|
3751
3668
|
typeof e == "number" && e > 0,
|
|
3752
3669
|
"Font size must be a positive number greater than 0.",
|
|
3753
3670
|
{ method: "fontSize", providedValue: e }
|
|
@@ -4339,7 +4256,7 @@ class I {
|
|
|
4339
4256
|
return this._isDisposed;
|
|
4340
4257
|
}
|
|
4341
4258
|
}
|
|
4342
|
-
class
|
|
4259
|
+
class O {
|
|
4343
4260
|
/**
|
|
4344
4261
|
* Create a {@link Textmodifier} instance for textmode rendering.
|
|
4345
4262
|
*
|
|
@@ -4401,10 +4318,10 @@ class N {
|
|
|
4401
4318
|
*/
|
|
4402
4319
|
static async create(e, t = {}) {
|
|
4403
4320
|
if (e instanceof HTMLCanvasElement || e instanceof HTMLVideoElement)
|
|
4404
|
-
return
|
|
4321
|
+
return k.create(e, t);
|
|
4405
4322
|
{
|
|
4406
4323
|
const r = e || {};
|
|
4407
|
-
return
|
|
4324
|
+
return k.create(null, r);
|
|
4408
4325
|
}
|
|
4409
4326
|
}
|
|
4410
4327
|
/**
|
|
@@ -4418,7 +4335,7 @@ class N {
|
|
|
4418
4335
|
* ```
|
|
4419
4336
|
*/
|
|
4420
4337
|
static setErrorLevel(e) {
|
|
4421
|
-
|
|
4338
|
+
_.setGlobalLevel(e);
|
|
4422
4339
|
}
|
|
4423
4340
|
/**
|
|
4424
4341
|
* Returns the current version of the `textmode.js` library.
|
|
@@ -4429,27 +4346,27 @@ class N {
|
|
|
4429
4346
|
* ```
|
|
4430
4347
|
*/
|
|
4431
4348
|
static get version() {
|
|
4432
|
-
return "0.1.6-beta.
|
|
4349
|
+
return "0.1.6-beta.4";
|
|
4433
4350
|
}
|
|
4434
4351
|
constructor() {
|
|
4435
4352
|
throw new Error("Textmode is a static class and cannot be instantiated.");
|
|
4436
4353
|
}
|
|
4437
4354
|
}
|
|
4438
|
-
const
|
|
4355
|
+
const Be = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
4439
4356
|
__proto__: null
|
|
4440
|
-
}, Symbol.toStringTag, { value: "Module" })),
|
|
4357
|
+
}, Symbol.toStringTag, { value: "Module" })), ke = O.create, Ve = O.setErrorLevel, ze = O.version;
|
|
4441
4358
|
export {
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
|
|
4450
|
-
|
|
4451
|
-
|
|
4452
|
-
|
|
4453
|
-
|
|
4454
|
-
|
|
4359
|
+
fe as TextmodeCanvas,
|
|
4360
|
+
Fe as TextmodeConversionPipeline,
|
|
4361
|
+
re as TextmodeErrorLevel,
|
|
4362
|
+
ue as TextmodeFont,
|
|
4363
|
+
de as TextmodeGrid,
|
|
4364
|
+
k as Textmodifier,
|
|
4365
|
+
Pe as converters,
|
|
4366
|
+
ke as create,
|
|
4367
|
+
O as default,
|
|
4368
|
+
Be as export,
|
|
4369
|
+
Ve as setErrorLevel,
|
|
4370
|
+
O as textmode,
|
|
4371
|
+
ze as version
|
|
4455
4372
|
};
|