insomni 0.2.0-alpha.0

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.
@@ -0,0 +1,298 @@
1
+ import { n as resolveRoot } from "./root-CHradZKM.mjs";
2
+ import { r as shapeText, t as measureBlockWidth } from "./shape-DfZP9Jdk.mjs";
3
+ import { r as Texture } from "./texture-dABoqFoP.mjs";
4
+ import { Font, MsdfGlyphAtlas as MsdfGlyphAtlas$1, loadFont, parseFont, parseFont as parseFont$1 } from "insomni-msdf-text";
5
+ //#region src/text/msdf-adapter.ts
6
+ var MsdfGlyphAtlas = class {
7
+ font;
8
+ _atlas;
9
+ _texture;
10
+ measureCache = /* @__PURE__ */ new Map();
11
+ measureCacheVersion = 0;
12
+ constructor(owner, font, options = {}) {
13
+ const device = resolveRoot(owner).device;
14
+ this.font = font;
15
+ this._atlas = new MsdfGlyphAtlas$1({
16
+ device,
17
+ font,
18
+ atlasSize: options.atlasSize,
19
+ atlasFontSize: options.atlasFontSize,
20
+ pxRange: options.pxRange,
21
+ label: options.label ?? `text-atlas:${font.family}`
22
+ });
23
+ this._texture = new Texture(this._atlas.texture, this._atlas.atlasSize, this._atlas.atlasSize);
24
+ }
25
+ get pxRange() {
26
+ return this._atlas.pxRange;
27
+ }
28
+ get atlasFontSize() {
29
+ return this._atlas.atlasFontSize;
30
+ }
31
+ get atlasSize() {
32
+ return this._atlas.atlasSize;
33
+ }
34
+ get texture() {
35
+ return this._texture;
36
+ }
37
+ get glyphCount() {
38
+ return this._atlas.glyphCount;
39
+ }
40
+ get destroyed() {
41
+ return this._atlas.destroyed;
42
+ }
43
+ get fillPercent() {
44
+ return this._atlas.fillPercent;
45
+ }
46
+ get version() {
47
+ return this._atlas.version;
48
+ }
49
+ getGlyph(codepoint) {
50
+ return this._atlas.getGlyph(codepoint);
51
+ }
52
+ getGlyphById(id) {
53
+ return this._atlas.getGlyphById(id);
54
+ }
55
+ measureText(text, options) {
56
+ const v = this._atlas.version;
57
+ if (this.measureCacheVersion !== v) {
58
+ this.measureCache.clear();
59
+ this.measureCacheVersion = v;
60
+ }
61
+ const simple = options.simple === true;
62
+ const lineHeight = options.lineHeight ?? options.fontSize * 1.2;
63
+ const key = `${options.fontSize}|${simple ? 1 : 0}|${options.maxWidth ?? -1}|${lineHeight}|${text}`;
64
+ const cached = this.measureCache.get(key);
65
+ if (cached !== void 0) return cached;
66
+ let metrics;
67
+ if (options.maxWidth === void 0) {
68
+ const width = measureBlockWidth(text, this.font, this, options.fontSize, simple);
69
+ let lineCount = 1;
70
+ if (!simple) {
71
+ for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) === 10) lineCount++;
72
+ }
73
+ metrics = {
74
+ width: Math.max(0, width),
75
+ height: lineCount * lineHeight
76
+ };
77
+ } else {
78
+ const block = shapeText(text, this.font, this, 0, 0, {
79
+ fontSize: options.fontSize,
80
+ maxWidth: options.maxWidth,
81
+ lineHeight: options.lineHeight,
82
+ simple
83
+ });
84
+ const width = Number.isFinite(block.bbox.maxX) ? block.bbox.maxX - block.bbox.minX : 0;
85
+ metrics = {
86
+ width: Math.max(0, width),
87
+ height: block.height
88
+ };
89
+ }
90
+ this.measureCache.set(key, metrics);
91
+ return metrics;
92
+ }
93
+ preload(text) {
94
+ this._atlas.preload(text);
95
+ }
96
+ destroy() {
97
+ this._atlas.destroy();
98
+ this._texture.destroy();
99
+ }
100
+ };
101
+ //#endregion
102
+ //#region src/text/embedded-font.ts
103
+ /** Family name for the embedded subset (its `name` table was dropped by subsetting). */
104
+ const EMBEDDED_FONT_FAMILY = "Lato";
105
+ /** Base64-encoded Lato Regular subset TTF (Latin-1 + common punctuation). */
106
+ const EMBEDDED_FONT_B64 = "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DygPKA72DygPKA8oDygPKA8oDygAAQBeAAMACAAJAAsADQAOAA8AEAAhACIAJAAlACcAKwAsAC0AMAAxADIAMwA1ADYANwA4ADkAOgA7ADwAPQBCAEMARgBHAEkATABOAE8AUABRAFMAVwBYAFkAWgBcAGoAawBtAG4AcAByAHMAdwB5AHoAewCAAIEAggCDAIQAhQCHAJAAkgCTAJQAlQCWAJkAmgCbAJwAnQCeAKAAoQCiAKMApAClAKYAqACpAKoAqwCxALIAswC0ALUAtgC4AL4AIAAD/xwACP8cAAv/HAAO/3gAIf/IACT/yAAo/8gAMP/IADL/yAA1/0wAN/9MADj/hgA6/2gAPf9MAFf/fABY/8IAWv98AGr/HABr/3gAbf94AHD/HAB3/3gAev8cAHv/eACH/8gAkv/IAJP/yACU/8gAlf/IAJb/yACY/8gAnf9oACwAB/98AA3/TAAP/0wAEP98ABv/xAAc/8QAIAAeACL/fAAr/zoARP+6AEX/ugBG/7oATv/EAE//xABQ/7oAUf/EAFL/ugBT/8QAVv/EAHX/xACA/3wAgf98AIL/fACD/3wAhP98AIX/fACG/3wAp/+6AKj/ugCp/7oAqv+6AKv/ugCw/7oAsf/EALL/ugCz/7oAtP+6ALX/ugC2/7oAuP+6ALn/xAC6/8QAu//EALz/xAA3AAP+3gAI/t4AC/7eAA0ANgAO/zoADwA2ACD/zgAh/7AAJP+wACj/sAAw/7AAMv+wADX/VAA3/0oAOP9oADr/LAA9/0oARP/cAEX/3ABG/9wAUP/cAFL/3ABX/5QAWP+wAFr/lABq/t4Aa/86AG3/OgBw/t4Acv82AHP/NgB3/zoAef82AHr+3gB7/zoAh/+wAJL/sACT/7AAlP+wAJX/sACW/7AAmP+wAJ3/LACn/9wAqP/cAKn/3ACq/9wAq//cALD/3ACy/9wAs//cALT/3AC1/9wAtv/cALj/3AAmAAf/dgAN/wgAD/8IABD/dgAi/3YAK/9KAEL/zgBE/+IARf/iAEb/4gBQ/+IAUv/iAID/dgCB/3YAgv92AIP/dgCE/3YAhf92AIb/dgCg/84Aof/OAKL/zgCj/84ApP/OAKX/zgCm/84Ap//iAKj/4gCp/+IAqv/iAKv/4gCw/+IAsv/iALP/4gC0/+IAtf/iALb/4gC4/+IAEgAh/9IAJP/SACj/0gAw/9IAMv/SADX/zAA2/9YAh//SAJL/0gCT/9IAlP/SAJX/0gCW/9IAmP/SAJn/1gCa/9YAm//WAJz/1gBLAAf/fAAN/0wADv9MAA//TAAQ/3wAG/9gABz/YAAh/54AIv98ACT/ngAo/54AK/84ADD/ngAy/54AQv8GAET/LgBF/y4ARv8uAEj/RABO/2AAT/9gAFD/LgBR/2AAUv8uAFP/YABU/14AVv9gAFf/TABY/3QAWf9wAFr/TABb/4gAa/9MAG3/TAB1/2AAd/9MAHv/TACA/3wAgf98AIL/fACD/3wAhP98AIX/fACG/3wAh/+eAJL/ngCT/54AlP+eAJX/ngCW/54AmP+eAKD/BgCh/wYAov8GAKP/BgCk/wYApf8GAKb/BgCn/y4AqP8uAKn/LgCq/y4Aq/8uALD/LgCx/2AAsv8uALP/LgC0/y4Atf8uALb/LgC4/y4Auf9gALr/YAC7/2AAvP9gAFYAAwAwAAf/eAAIADAACwAwAA3/QAAO/5AAD/9AABD/eAAb/6gAHP+oACAAMAAh/8wAIv94ACT/zAAo/8wAK/9oADD/zAAy/8wAQv+MAET/jABF/4wARv+MAEf/4gBI/3gATv+oAE//qABQ/4wAUf+oAFL/jABT/6gAVP+WAFX/1gBW/6gAV//QAFn/zABa/9AAW/+uAGoAMABr/5AAbf+QAHAAMAByADoAcwA6AHX/qAB3/5AAeQA6AHoAMAB7/5AAgP94AIH/eACC/3gAg/94AIT/eACF/3gAhv94AIf/zACS/8wAk//MAJT/zACV/8wAlv/MAJj/zACg/4wAof+MAKL/jACj/4wApP+MAKX/jACm/4wAp/+MAKj/jACp/4wAqv+MAKv/jACw/4wAsf+oALL/jACz/4wAtP+MALX/jAC2/4wAuP+MALn/qAC6/6gAu/+oALz/qAA3AAMAMAAH/6IACAAwAAsAMAAN/4YADv/gAA//hgAQ/6IAIAAiACL/ogAr/5oAQv+oAET/4ABF/+AARv/gAEj/ngBQ/+AAUv/gAFT/0gBqADAAa//gAG3/4ABwADAAcgAwAHMAMAB3/+AAeQAwAHoAMAB7/+AAgP+iAIH/ogCC/6IAg/+iAIT/ogCF/6IAhv+iAKD/qACh/6gAov+oAKP/qACk/6gApf+oAKb/qACn/+AAqP/gAKn/4ACq/+AAq//gALD/4ACy/+AAs//gALT/4AC1/+AAtv/gALj/4AAnAA7/wgAh/+IAJP/iACj/4gAw/+IAMv/iAET/3ABF/9wARv/cAEf/zABQ/9wAUv/cAFX/rgBX/74AWP/IAFr/vgBr/8IAbf/CAHf/wgB7/8IAh//iAJL/4gCT/+IAlP/iAJX/4gCW/+IAmP/iAKf/3ACo/9wAqf/cAKr/3ACr/9wAsP/cALL/3ACz/9wAtP/cALX/3AC2/9wAuP/cACYADv+6ACAAIgAh/8YAJP/GACj/xgAw/8YAMv/GAET/2gBF/9oARv/aAFD/2gBS/9oAVP/kAFf/2ABa/9gAa/+6AG3/ugB3/7oAe/+6AIf/xgCS/8YAk//GAJT/xgCV/8YAlv/GAJj/xgCn/9oAqP/aAKn/2gCq/9oAq//aALD/2gCy/9oAs//aALT/2gC1/9oAtv/aALj/2gALAAMARAAIAEQACwBEAA3/fgAP/34AagBEAHAARAByAGQAcwBkAHkAZAB6AEQACgAN/3wAD/98AEL/2gCg/9oAof/aAKL/2gCj/9oApP/aAKX/2gCm/9oAAgAN/8IAD//CABEARP/EAEX/xABG/8QAUP/EAFL/xACn/8QAqP/EAKn/xACq/8QAq//EALD/xACy/8QAs//EALT/xAC1/8QAtv/EALj/xAAdAAf/rgAN/3wAD/98ABD/rgAi/64ARP/mAEX/5gBG/+YAUP/mAFL/5gCA/64Agf+uAIL/rgCD/64AhP+uAIX/rgCG/64Ap//mAKj/5gCp/+YAqv/mAKv/5gCw/+YAsv/mALP/5gC0/+YAtf/mALb/5gC4/+YAHQAh/9gAJP/YACj/2AAw/9gAMv/YAET/4ABF/+AARv/gAFD/4ABS/+AAh//YAJL/2ACT/9gAlP/YAJX/2ACW/9gAmP/YAKf/4ACo/+AAqf/gAKr/4ACr/+AAsP/gALL/4ACz/+AAtP/gALX/4AC2/+AAuP/gAA8AB/9IABD/SAAi/0gANwA6ADgAOgA6ACgAPQA6AID/SACB/0gAgv9IAIP/SACE/0gAhf9IAIb/SACdACgAOwAH/0oADf8cAA7/TgAP/xwAEP9KACH/0gAi/0oAJP/SACj/0gAw/9IAMv/SADcAMAA4ADAAOgAeAD0AMABC/8AARP+kAEX/pABG/6QAUP+kAFL/pABr/04Abf9OAHf/TgB7/04AgP9KAIH/SgCC/0oAg/9KAIT/SgCF/0oAhv9KAIf/0gCS/9IAk//SAJT/0gCV/9IAlv/SAJj/0gCdAB4AoP/AAKH/wACi/8AAo//AAKT/wACl/8AApv/AAKf/pACo/6QAqf+kAKr/pACr/6QAsP+kALL/pACz/6QAtP+kALX/pAC2/6QAuP+kABoAA/9OAAf/zAAI/04AC/9OAA3/eAAP/3gAEP/MACL/zAA1/0wAN/+QADj/4AA5/8IAOv9gADv/0gA9/5AAav9OAHD/TgB6/04AgP/MAIH/zACC/8wAg//MAIT/zACF/8wAhv/MAJ3/YAApAAP/SgAI/0oAC/9KAA7/zAAg/8gAIf/WACT/1gAo/9YAKwAyADD/1gAy/9YANf98ADb/yAA3/3gAOP+sADr/XAA9/3gAV/+uAFr/rgBq/0oAa//MAG3/zABw/0oAcv9IAHP/SAB3/8wAef9IAHr/SgB7/8wAh//WAJL/1gCT/9YAlP/WAJX/1gCW/9YAmP/WAJn/yACa/8gAm//IAJz/yACd/1wABQAO/2oAa/9qAG3/agB3/2oAe/9qAAwAB//IAA3/zgAP/84AEP/IACL/yACA/8gAgf/IAIL/yACD/8gAhP/IAIX/yACG/8gAVAADAB4AB/9cAAgAHgALAB4ADf9oAA7/YAAP/2gAEP9cABv/hgAc/4YAIAAiACH/sAAi/1wAJP+wACj/sAAr/zgAMP+wADL/sABC/4AARP9gAEX/YABG/2AASP9UAE7/hgBP/4YAUP9gAFH/hgBS/2AAU/+GAFT/gABW/4YAV/+cAFj/pABZ/3wAWv+cAGoAHgBr/2AAbf9gAHAAHgByADIAcwAyAHX/hgB3/2AAeQAyAHoAHgB7/2AAgP9cAIH/XACC/1wAg/9cAIT/XACF/1wAhv9cAIf/sACS/7AAk/+wAJT/sACV/7AAlv+wAJj/sACg/4AAof+AAKL/gACj/4AApP+AAKX/gACm/4AAp/9gAKj/YACp/2AAqv9gAKv/YACw/2AAsf+GALL/YACz/2AAtP9gALX/YAC2/2AAuP9gALn/hgC6/4YAu/+GALz/hgAcAAP/0gAH/9YACP/SAAr/2AAL/9IADf/IAA//yAAQ/9YAIv/WADX/ngA3/8wAOf/iADr/sAA7/7oAPf/MAD7/2ABe/9gAav/SAHD/0gB6/9IAgP/WAIH/1gCC/9YAg//WAIT/1gCF/9YAhv/WAJ3/sAAMAAP/uAAI/7gAC/+4AFf/4ABY//AAWv/gAGr/uABw/7gAcv+4AHP/uAB5/7gAev+4AA8AA/+kAAj/pAAK/+AAC/+kADf/jAA4/+AAPf+MAD7/4ABX/+YAWf/EAFr/5gBe/+AAav+kAHD/pAB6/6QAAQAAAAoAJAAyAAJERkxUAA5sYXRuAA4ABAAAAAD//wABAAAAAWxpZ2EACAAAAAEAAAABAAQABAAAAAEACAABABoAAQAIAAIABgAMAMQAAgBKAMUAAgBNAAEAAQBHAAA=";
107
+ /**
108
+ * Decode the embedded font bytes into an ArrayBuffer.
109
+ * Synchronous, allocation-only — no network, no I/O, SSR-safe.
110
+ */
111
+ function decodeEmbeddedFont() {
112
+ return Uint8Array.from(atob(EMBEDDED_FONT_B64), (c) => c.charCodeAt(0)).buffer;
113
+ }
114
+ //#endregion
115
+ //#region src/text/cpu-glyph-atlas.ts
116
+ var CpuGlyphAtlas = class {
117
+ font;
118
+ pxRange;
119
+ atlasFontSize;
120
+ atlasSize;
121
+ cache = /* @__PURE__ */ new Map();
122
+ /** Glyphs indexed by `atlasGlyphId`. Append-only; mirrors MsdfGlyphAtlas. */
123
+ _glyphList = [];
124
+ /** Bumps every time `_glyphList` grows. */
125
+ _version = 0;
126
+ measureCache = /* @__PURE__ */ new Map();
127
+ _destroyed = false;
128
+ constructor(font, options = {}) {
129
+ this.font = font;
130
+ this.atlasSize = options.atlasSize ?? 2048;
131
+ this.atlasFontSize = options.atlasFontSize ?? 64;
132
+ this.pxRange = options.pxRange ?? 8;
133
+ }
134
+ get version() {
135
+ return this._version;
136
+ }
137
+ get glyphCount() {
138
+ return this._glyphList.length;
139
+ }
140
+ get destroyed() {
141
+ return this._destroyed;
142
+ }
143
+ /** Always 0 — no shelf packer needed (no texture). */
144
+ get fillPercent() {
145
+ return 0;
146
+ }
147
+ /**
148
+ * CPU atlas has no GPU texture. Throws if accessed so misuse is loud, not
149
+ * silent corruption. The SVG renderer never reads `texture` — it gates on
150
+ * `layer.atlas` and decodes via `getGlyphById` (`svg-renderer.ts:285`).
151
+ */
152
+ get texture() {
153
+ throw new Error("CpuGlyphAtlas has no GPU texture — SVG/measure only; use SdfGlyphAtlas/MsdfGlyphAtlas for GPU rendering.");
154
+ }
155
+ /**
156
+ * Return the glyph entry for `codepoint`, computing metrics from the font
157
+ * outline on first request. UVs are set to 0 (no texture).
158
+ *
159
+ * Mirrors `MsdfGlyphAtlas.getGlyph` (atlas.ts:133-232) with the
160
+ * shelf-packer, `generate()`, and UV-from-origin math removed.
161
+ */
162
+ getGlyph(codepoint) {
163
+ const cached = this.cache.get(codepoint);
164
+ if (cached !== void 0) return cached;
165
+ const outline = this.font.getOutline(codepoint);
166
+ if (!outline) {
167
+ this.cache.set(codepoint, null);
168
+ return null;
169
+ }
170
+ if (outline.contours.length === 0) {
171
+ const entry = {
172
+ codepoint,
173
+ atlasGlyphId: this._glyphList.length,
174
+ uvMinX: 0,
175
+ uvMinY: 0,
176
+ uvMaxX: 0,
177
+ uvMaxY: 0,
178
+ pxRange: this.pxRange,
179
+ advance: outline.advance,
180
+ bearingX: 0,
181
+ bearingY: 0,
182
+ width: 0,
183
+ height: 0
184
+ };
185
+ this.cache.set(codepoint, entry);
186
+ this._glyphList.push(entry);
187
+ this._version++;
188
+ return entry;
189
+ }
190
+ const emPad = this.pxRange / this.atlasFontSize / 2;
191
+ const minX = outline.bbox.minX - emPad;
192
+ const minY = outline.bbox.minY - emPad;
193
+ const maxX = outline.bbox.maxX + emPad;
194
+ const maxY = outline.bbox.maxY + emPad;
195
+ const entry = {
196
+ codepoint,
197
+ atlasGlyphId: this._glyphList.length,
198
+ uvMinX: 0,
199
+ uvMinY: 0,
200
+ uvMaxX: 0,
201
+ uvMaxY: 0,
202
+ pxRange: this.pxRange,
203
+ advance: outline.advance,
204
+ bearingX: minX,
205
+ bearingY: maxY,
206
+ width: maxX - minX,
207
+ height: maxY - minY
208
+ };
209
+ this.cache.set(codepoint, entry);
210
+ this._glyphList.push(entry);
211
+ this._version++;
212
+ return entry;
213
+ }
214
+ /**
215
+ * Fetch a glyph by its `atlasGlyphId` (allocation order). O(1) array lookup.
216
+ * This is the decode contract: `svg-renderer.ts:512` calls this to reconstruct
217
+ * the original codepoint from a glyph-pack instance.
218
+ */
219
+ getGlyphById(id) {
220
+ return this._glyphList[id];
221
+ }
222
+ /**
223
+ * Verbatim copy of `msdf-adapter.ts:75-109` — depends only on `this.font`
224
+ * and `this` as the GlyphAtlas shaper arg (no GPU involvement).
225
+ */
226
+ measureText(text, options) {
227
+ const simple = options.simple === true;
228
+ const lineHeight = options.lineHeight ?? options.fontSize * 1.2;
229
+ const key = `${options.fontSize}|${simple ? 1 : 0}|${options.maxWidth ?? -1}|${lineHeight}|${text}`;
230
+ const cached = this.measureCache.get(key);
231
+ if (cached !== void 0) return cached;
232
+ let metrics;
233
+ if (options.maxWidth === void 0) {
234
+ const width = measureBlockWidth(text, this.font, this, options.fontSize, simple);
235
+ let lineCount = 1;
236
+ if (!simple) {
237
+ for (let i = 0; i < text.length; i++) if (text.charCodeAt(i) === 10) lineCount++;
238
+ }
239
+ metrics = {
240
+ width: Math.max(0, width),
241
+ height: lineCount * lineHeight
242
+ };
243
+ } else {
244
+ const block = shapeText(text, this.font, this, 0, 0, {
245
+ fontSize: options.fontSize,
246
+ maxWidth: options.maxWidth,
247
+ lineHeight: options.lineHeight,
248
+ simple
249
+ });
250
+ const width = Number.isFinite(block.bbox.maxX) ? block.bbox.maxX - block.bbox.minX : 0;
251
+ metrics = {
252
+ width: Math.max(0, width),
253
+ height: block.height
254
+ };
255
+ }
256
+ this.measureCache.set(key, metrics);
257
+ return metrics;
258
+ }
259
+ /** Pre-warm the glyph cache for a string of text. No GPU work. */
260
+ preload(text) {
261
+ for (const ch of text) this.getGlyph(ch.codePointAt(0));
262
+ }
263
+ /** Clear caches and mark as destroyed. */
264
+ destroy() {
265
+ if (this._destroyed) return;
266
+ this._destroyed = true;
267
+ this.cache.clear();
268
+ this._glyphList.length = 0;
269
+ }
270
+ };
271
+ /**
272
+ * Module-scope lazy singleton: parses the embedded Lato subset font ONCE and
273
+ * reuses the atlas across every `toSVG()` call. O(1) after first load.
274
+ *
275
+ * Do NOT destroy this instance — it is shared across all export calls.
276
+ */
277
+ let _shared = null;
278
+ function sharedCpuGlyphAtlas() {
279
+ if (_shared === null) _shared = new CpuGlyphAtlas(parseFont$1(decodeEmbeddedFont(), { family: EMBEDDED_FONT_FAMILY }));
280
+ return _shared;
281
+ }
282
+ /**
283
+ * Create a non-singleton `CpuGlyphAtlas`, optionally with a custom font.
284
+ *
285
+ * - Pass `font` (an already-parsed `Font`) for zero-overhead construction.
286
+ * - Pass `fontBytes` (ArrayBuffer or Uint8Array) to parse on construction.
287
+ * - Pass neither to fall back to the embedded Lato subset (same font as the
288
+ * shared singleton, but a fresh atlas instance).
289
+ */
290
+ function createCpuGlyphAtlas(opts = {}) {
291
+ let font;
292
+ if (opts.font !== void 0) font = opts.font;
293
+ else if (opts.fontBytes !== void 0) font = parseFont$1(opts.fontBytes);
294
+ else font = parseFont$1(decodeEmbeddedFont(), { family: EMBEDDED_FONT_FAMILY });
295
+ return new CpuGlyphAtlas(font, opts.options);
296
+ }
297
+ //#endregion
298
+ export { CpuGlyphAtlas, Font, MsdfGlyphAtlas, createCpuGlyphAtlas, loadFont, parseFont, sharedCpuGlyphAtlas };
@@ -0,0 +1,131 @@
1
+ import { n as resolveRoot } from "./root-CHradZKM.mjs";
2
+ //#region src/shared/texture.ts
3
+ let _nextTextureId = 0;
4
+ /**
5
+ * Caller-owned GPU texture wrapper used by sprite APIs.
6
+ *
7
+ * `Layer`, `SpriteAtlas`, `GridAtlas`, and `Renderer2D` may retain references
8
+ * to a `Texture`, but none of them take ownership of it or destroy it on the caller's behalf.
9
+ */
10
+ var Texture = class {
11
+ id;
12
+ gpuTexture;
13
+ view;
14
+ width;
15
+ height;
16
+ _destroyed = false;
17
+ constructor(gpuTexture, width, height) {
18
+ this.id = _nextTextureId++;
19
+ this.gpuTexture = gpuTexture;
20
+ this.view = gpuTexture.createView();
21
+ this.width = width;
22
+ this.height = height;
23
+ }
24
+ /** Sub-region by pixel coordinates. */
25
+ region(x, y, w, h) {
26
+ this.ensureAlive();
27
+ assertTextureRect(x, y, w, h, this.width, this.height);
28
+ return {
29
+ texture: this,
30
+ uvMin: [x / this.width, y / this.height],
31
+ uvMax: [(x + w) / this.width, (y + h) / this.height]
32
+ };
33
+ }
34
+ /** Sub-region by normalized UV coordinates. */
35
+ regionUV(u0, v0, u1, v1) {
36
+ this.ensureAlive();
37
+ return {
38
+ texture: this,
39
+ uvMin: [u0, v0],
40
+ uvMax: [u1, v1]
41
+ };
42
+ }
43
+ get destroyed() {
44
+ return this._destroyed;
45
+ }
46
+ /**
47
+ * Release the underlying GPU texture.
48
+ *
49
+ * Destroying a texture that is still referenced by a `Layer` is a caller error.
50
+ * Future sprite draws that still reference it will throw a clear runtime error.
51
+ */
52
+ destroy() {
53
+ if (this._destroyed) return;
54
+ this._destroyed = true;
55
+ this.gpuTexture.destroy();
56
+ }
57
+ ensureAlive() {
58
+ if (this._destroyed) throw new Error("Texture has been destroyed.");
59
+ }
60
+ };
61
+ var SpriteAtlas = class {
62
+ _regions;
63
+ constructor(texture, regions) {
64
+ this._regions = new Map(Object.entries(regions).map(([name, def]) => [name, texture.region(def.x, def.y, def.w, def.h)]));
65
+ }
66
+ region(name) {
67
+ const r = this._regions.get(name);
68
+ if (!r) throw new Error(`SpriteAtlas: region "${name}" not found.`);
69
+ return r;
70
+ }
71
+ };
72
+ var GridAtlas = class {
73
+ texture;
74
+ cellW;
75
+ cellH;
76
+ cols;
77
+ rows;
78
+ constructor(texture, options) {
79
+ this.texture = texture;
80
+ this.cellW = options.cell[0];
81
+ this.cellH = options.cell[1];
82
+ if (this.cellW <= 0 || this.cellH <= 0) throw new Error("GridAtlas cell dimensions must be positive.");
83
+ const maxCols = Math.floor(texture.width / this.cellW);
84
+ const maxRows = Math.floor(texture.height / this.cellH);
85
+ if (maxCols < 1 || maxRows < 1) throw new Error("GridAtlas cell dimensions must fit inside the texture.");
86
+ this.cols = options.cols ?? maxCols;
87
+ this.rows = options.rows ?? maxRows;
88
+ if (!Number.isInteger(this.cols) || !Number.isInteger(this.rows) || this.cols < 1 || this.rows < 1) throw new Error("GridAtlas rows and cols must be positive integers.");
89
+ if (this.cols > maxCols || this.rows > maxRows) throw new Error(`GridAtlas ${this.rows}x${this.cols} exceeds the ${maxRows}x${maxCols} grid that fits in this texture.`);
90
+ }
91
+ /** Get a frame by linear index, or by (row, col). */
92
+ frame(indexOrRow, col) {
93
+ const row = col === void 0 ? Math.floor(indexOrRow / this.cols) : indexOrRow;
94
+ const c = col === void 0 ? indexOrRow % this.cols : col;
95
+ if (!Number.isInteger(row) || !Number.isInteger(c) || row < 0 || row >= this.rows || c < 0 || c >= this.cols) throw new Error(`GridAtlas frame (${row}, ${c}) is out of bounds for a ${this.rows}x${this.cols} atlas.`);
96
+ return this.texture.region(c * this.cellW, row * this.cellH, this.cellW, this.cellH);
97
+ }
98
+ };
99
+ /**
100
+ * Load a texture from a URL or any ImageBitmapSource.
101
+ * The result is in premultiplied alpha format, matching the renderer's blend state.
102
+ *
103
+ * The returned `Texture` remains caller-owned. The renderer may cache per-texture bind groups
104
+ * while it is in use, but it will never destroy the texture for you.
105
+ */
106
+ async function loadTexture(owner, src, options = {}) {
107
+ const device = resolveRoot(owner).device;
108
+ const bitmap = typeof src === "string" ? await createImageBitmap(await (await fetch(src)).blob()) : await createImageBitmap(src);
109
+ const width = bitmap.width;
110
+ const height = bitmap.height;
111
+ const format = options.format ?? "rgba8unorm";
112
+ const gpuTexture = device.createTexture({
113
+ label: options.label,
114
+ size: [width, height],
115
+ format,
116
+ usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
117
+ });
118
+ device.queue.copyExternalImageToTexture({ source: bitmap }, {
119
+ texture: gpuTexture,
120
+ premultipliedAlpha: true
121
+ }, [width, height]);
122
+ bitmap.close();
123
+ return new Texture(gpuTexture, width, height);
124
+ }
125
+ function assertTextureRect(x, y, w, h, textureWidth, textureHeight) {
126
+ if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(w) || !Number.isFinite(h)) throw new Error("Texture region coordinates must be finite.");
127
+ if (w <= 0 || h <= 0) throw new Error("Texture region dimensions must be positive.");
128
+ if (x < 0 || y < 0 || x + w > textureWidth || y + h > textureHeight) throw new Error(`Texture region (${x}, ${y}, ${w}, ${h}) is out of bounds for a ${textureWidth}x${textureHeight} texture.`);
129
+ }
130
+ //#endregion
131
+ export { loadTexture as i, SpriteAtlas as n, Texture as r, GridAtlas as t };
@@ -0,0 +1,2 @@
1
+ import { _ as ViewportLike, b as worldCullBounds, d as CameraPanBoundsOptions, f as CameraViewport, g as Viewport, h as PanBoundsMargins, m as PanBoundsMargin, p as CameraViewportOptions, u as CameraInternal, v as ZoomFactor, y as createViewport } from "./camera-view-DHmMiKvP.mjs";
2
+ export { CameraInternal, CameraPanBoundsOptions, CameraViewport, CameraViewportOptions, PanBoundsMargin, PanBoundsMargins, Viewport, ViewportLike, ZoomFactor, createViewport, worldCullBounds };