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,85 @@
1
+ import { r as Renderer2D$1, vt as Layer } from "./renderer-DzZqd1bY.mjs";
2
+ import { N as FrameRect } from "./camera-view-DHmMiKvP.mjs";
3
+ import { Damage, DamageKind, DirtyRegion, FrameTiming as SpatialFrameTiming, PointerHandler, PointerRouter, Rect, Rect as Rect$1, RectSpace, Renderer2D, Renderer2D as SpatialRenderer2D, SceneNode, SceneNode as SceneNode$1, SceneNodeOptions, SceneRoot, SceneRoot as SceneRoot$1, SceneRootOptions, SceneRootOptions as SceneRootOptions$1, SpatialPointerEvent, pointInRect, rectClamp, rectEquals, rectOverlaps, unionRects } from "@dirtytalk/spatial";
4
+ import { DirtyChannel, ManualScheduler, MicrotaskScheduler, Observable, RAFScheduler, Scheduler, Signal, Space, SyncScheduler } from "@dirtytalk/engine";
5
+
6
+ //#region src/spatial.d.ts
7
+ /** Convert an insomni `FrameRect` ({x,y,width,height}) to a spatial `Rect`. */
8
+ declare function frameToRect(frame: FrameRect): Rect;
9
+ /** Convert a spatial `Rect` to an insomni `FrameRect`. */
10
+ declare function rectToFrame(rect: Rect): FrameRect;
11
+ /** Build a `Rect` from loose x/y/width/height fields. */
12
+ declare function rectOf(x: number, y: number, width: number, height: number): Rect;
13
+ interface LayerRendererOptions {
14
+ /**
15
+ * Clear `layer` at the start of every frame. Default `true` (full-canvas
16
+ * model — nodes re-emit each frame). Set `false` only for retained layers
17
+ * that you mutate incrementally and never want auto-cleared.
18
+ */
19
+ clearLayer?: boolean;
20
+ /**
21
+ * Extra layers submitted after the scene layer, in order (e.g. a HUD
22
+ * overlay). Re-read each frame so the list can change between frames.
23
+ */
24
+ extraLayers?: () => readonly Layer[];
25
+ /** Hook invoked at the top of every frame, before the paint walk. */
26
+ onBeginFrame?: (regions: readonly Rect[]) => void;
27
+ /** Hook invoked after the paint walk, before the GPU submit. */
28
+ onEndFrame?: () => void;
29
+ /**
30
+ * Thunk reporting whether the owning root is in `fullFrame` mode. When it
31
+ * returns `true`, the GPU frame is submitted as a full clear+repaint; when
32
+ * `false`, the damage rects drive a partial redraw (on a `persistent`
33
+ * renderer). Lets {@link GpuSceneRoot} pass its live `fullFrame` flag without
34
+ * a construction-order cycle. Defaults to always-full.
35
+ */
36
+ isFullFrame?: () => boolean;
37
+ }
38
+ /**
39
+ * A spatial `Renderer2D` that records the most recent damage regions (for a
40
+ * future scissor path) and drives `gpu.render([...])` on `endFrame`.
41
+ */
42
+ interface LayerRenderer extends Renderer2D {
43
+ /** Damage rects handed to the most recent `beginFrame`. */
44
+ readonly lastRegions: readonly Rect[];
45
+ }
46
+ declare function createLayerRenderer(gpu: Renderer2D$1, layer: Layer, options?: LayerRendererOptions): LayerRenderer;
47
+ declare abstract class GpuSceneNode extends SceneNode {
48
+ /** Emit this node's geometry into the GPU layer. */
49
+ abstract drawSelf(layer: Layer): void;
50
+ paint(_layer: unknown): void;
51
+ /** Walk the parent chain to the owning GpuSceneRoot, or null if detached. */
52
+ protected gpuRoot(): GpuSceneRoot | null;
53
+ /** Mark a visual-only change: repaint, no data/layout rebuild. */
54
+ invalidatePaint(rect?: Rect): void;
55
+ /** Mark a layout change (bounds/children moved). Triggers doLayout + paint. */
56
+ invalidateLayout(rect?: Rect): void;
57
+ /** Mark a data change (inputs replaced). Triggers rebuildData → layout → paint. */
58
+ invalidateData(rect?: Rect): void;
59
+ }
60
+ interface GpuSceneRootOptions extends SceneRootOptions, LayerRendererOptions {
61
+ /**
62
+ * Repaint every node on any damage and ignore the per-node cull. Default
63
+ * `true` for the full-canvas model (the scene layer is cleared each frame,
64
+ * so culled-out nodes would otherwise vanish). Set `false` only when the
65
+ * scene layer / its children are retained between frames.
66
+ */
67
+ fullFrame?: boolean;
68
+ }
69
+ declare class GpuSceneRoot extends SceneRoot {
70
+ /** The scene layer that descendant nodes paint into. */
71
+ readonly layer: Layer;
72
+ /** The underlying WebGPU renderer. */
73
+ readonly gpu: Renderer2D$1;
74
+ constructor(gpu: Renderer2D$1, layer: Layer, options?: GpuSceneRootOptions);
75
+ paint(_layer: unknown): void;
76
+ /**
77
+ * Force a full repaint on the next scheduled frame. Use when widget internals
78
+ * are mutated outside a damage-tracked setter; normal state changes mark their
79
+ * own damage and don't need this. (`setBounds` to the same rect is a no-op, so
80
+ * it can't be used for this.)
81
+ */
82
+ requestPaint(): void;
83
+ }
84
+ //#endregion
85
+ export { frameToRect as A, Signal as C, SpatialRenderer2D as D, SpatialPointerEvent as E, rectOverlaps as F, rectToFrame as I, unionRects as L, rectClamp as M, rectEquals as N, SyncScheduler as O, rectOf as P, Scheduler as S, SpatialFrameTiming as T, RectSpace as _, GpuSceneNode as a, SceneRoot$1 as b, LayerRenderer as c, MicrotaskScheduler as d, Observable as f, Rect$1 as g, RAFScheduler as h, DirtyRegion as i, pointInRect as j, createLayerRenderer as k, LayerRendererOptions as l, PointerRouter as m, DamageKind as n, GpuSceneRoot as o, PointerHandler as p, DirtyChannel as r, GpuSceneRootOptions as s, Damage as t, ManualScheduler as u, SceneNode$1 as v, Space as w, SceneRootOptions$1 as x, SceneNodeOptions as y };
@@ -0,0 +1,77 @@
1
+ //#region src/gpu/spatial-hash.ts
2
+ const SPATIAL_HASH_WORKGROUP_SIZE = 64;
3
+ const SPATIAL_HASH_PARAMS_BYTES = 32;
4
+ const SPATIAL_HASH_PARAMS_WGSL = `
5
+ struct SpatialHashParams {
6
+ rangeStart: u32,
7
+ rangeCount: u32,
8
+ bucketMask: u32,
9
+ bucketCount: u32,
10
+ invCellSize: f32,
11
+ weight: f32,
12
+ _pad0: f32,
13
+ _pad1: f32,
14
+ };
15
+
16
+ const EMPTY_SLOT: u32 = 0xffffffffu;
17
+ const DEAD_CELL_COORD: i32 = 2147483647;
18
+
19
+ fn hashCell(cell: vec2i, mask: u32) -> u32 {
20
+ let x = bitcast<u32>(cell.x);
21
+ let y = bitcast<u32>(cell.y);
22
+ var h = x * 0x9e3779b9u;
23
+ h = (h << 6u) ^ (h >> 2u) ^ (y * 0x85ebca6bu);
24
+ return h & mask;
25
+ }
26
+
27
+ fn worldCell(pos: vec2f, invCellSize: f32) -> vec2i {
28
+ return vec2i(floor(pos * invCellSize));
29
+ }
30
+ `;
31
+ const CLEAR_SPATIAL_HASH_WGSL = `${SPATIAL_HASH_PARAMS_WGSL}
32
+ @group(0) @binding(0) var<storage, read_write> heads: array<atomic<u32>>;
33
+ @group(0) @binding(1) var<uniform> params: SpatialHashParams;
34
+
35
+ @compute @workgroup_size(64)
36
+ fn main(@builtin(global_invocation_id) gid: vec3u) {
37
+ let i = gid.x;
38
+ if (i >= params.bucketCount) {
39
+ return;
40
+ }
41
+ atomicStore(&heads[i], EMPTY_SLOT);
42
+ }
43
+ `;
44
+ const BUILD_SPATIAL_HASH_WGSL = `${SPATIAL_HASH_PARAMS_WGSL}
45
+ @group(0) @binding(0) var<storage, read_write> heads: array<atomic<u32>>;
46
+ @group(0) @binding(1) var<storage, read_write> next: array<u32>;
47
+ @group(0) @binding(2) var<storage, read_write> cells: array<vec2i>;
48
+ @group(0) @binding(3) var<storage, read> nodeIds: array<u32>;
49
+ @group(0) @binding(4) var<storage, read> positions: array<vec4f>;
50
+ @group(0) @binding(5) var<storage, read> alive: array<u32>;
51
+ @group(0) @binding(6) var<uniform> params: SpatialHashParams;
52
+
53
+ @compute @workgroup_size(64)
54
+ fn main(@builtin(global_invocation_id) gid: vec3u) {
55
+ let role = gid.x;
56
+ if (role >= params.rangeCount) {
57
+ return;
58
+ }
59
+
60
+ let entry = params.rangeStart + role;
61
+ let nodeId = nodeIds[entry];
62
+ next[entry] = EMPTY_SLOT;
63
+
64
+ if (alive[nodeId] == 0u) {
65
+ cells[entry] = vec2i(DEAD_CELL_COORD);
66
+ return;
67
+ }
68
+
69
+ let cell = worldCell(positions[nodeId].xy, params.invCellSize);
70
+ cells[entry] = cell;
71
+ let bucket = hashCell(cell, params.bucketMask);
72
+ let prev = atomicExchange(&heads[bucket], entry);
73
+ next[entry] = prev;
74
+ }
75
+ `;
76
+ //#endregion
77
+ export { SPATIAL_HASH_WORKGROUP_SIZE as a, SPATIAL_HASH_PARAMS_WGSL as i, CLEAR_SPATIAL_HASH_WGSL as n, SPATIAL_HASH_PARAMS_BYTES as r, BUILD_SPATIAL_HASH_WGSL as t };
@@ -0,0 +1,2 @@
1
+ import { A as frameToRect, C as Signal, D as SpatialRenderer2D, E as SpatialPointerEvent, F as rectOverlaps, I as rectToFrame, L as unionRects, M as rectClamp, N as rectEquals, O as SyncScheduler, P as rectOf, S as Scheduler, T as SpatialFrameTiming, _ as RectSpace, a as GpuSceneNode, b as SceneRoot, c as LayerRenderer, d as MicrotaskScheduler, f as Observable, g as Rect, h as RAFScheduler, i as DirtyRegion, j as pointInRect, k as createLayerRenderer, l as LayerRendererOptions, m as PointerRouter, n as DamageKind, o as GpuSceneRoot, p as PointerHandler, r as DirtyChannel, s as GpuSceneRootOptions, t as Damage, u as ManualScheduler, v as SceneNode, w as Space, x as SceneRootOptions, y as SceneNodeOptions } from "./spatial-Bd3Ay8I2.mjs";
2
+ export { Damage, DamageKind, DirtyChannel, DirtyRegion, GpuSceneNode, GpuSceneRoot, GpuSceneRootOptions, LayerRenderer, LayerRendererOptions, ManualScheduler, MicrotaskScheduler, Observable, PointerHandler, PointerRouter, RAFScheduler, Rect, RectSpace, SceneNode, SceneNodeOptions, SceneRoot, SceneRootOptions, Scheduler, Signal, Space, SpatialFrameTiming, SpatialPointerEvent, SpatialRenderer2D, SyncScheduler, createLayerRenderer, frameToRect, pointInRect, rectClamp, rectEquals, rectOf, rectOverlaps, rectToFrame, unionRects };
@@ -0,0 +1,121 @@
1
+ import { PointerRouter, RectSpace, SceneNode, SceneNode as SceneNode$1, SceneRoot, SceneRoot as SceneRoot$1, pointInRect, rectClamp, rectEquals, rectOverlaps, unionRects } from "@dirtytalk/spatial";
2
+ import { DirtyChannel, ManualScheduler, MicrotaskScheduler, RAFScheduler, Signal, SyncScheduler } from "@dirtytalk/engine";
3
+ //#region src/spatial.ts
4
+ /** Convert an insomni `FrameRect` ({x,y,width,height}) to a spatial `Rect`. */
5
+ function frameToRect(frame) {
6
+ return {
7
+ x: frame.x,
8
+ y: frame.y,
9
+ w: frame.width,
10
+ h: frame.height
11
+ };
12
+ }
13
+ /** Convert a spatial `Rect` to an insomni `FrameRect`. */
14
+ function rectToFrame(rect) {
15
+ return {
16
+ x: rect.x,
17
+ y: rect.y,
18
+ width: rect.w,
19
+ height: rect.h
20
+ };
21
+ }
22
+ /** Build a `Rect` from loose x/y/width/height fields. */
23
+ function rectOf(x, y, width, height) {
24
+ return {
25
+ x,
26
+ y,
27
+ w: width,
28
+ h: height
29
+ };
30
+ }
31
+ function createLayerRenderer(gpu, layer, options = {}) {
32
+ const clearLayer = options.clearLayer ?? true;
33
+ let lastRegions = [];
34
+ return {
35
+ get lastRegions() {
36
+ return lastRegions;
37
+ },
38
+ beginFrame(regions) {
39
+ lastRegions = regions;
40
+ if (clearLayer) layer.clear();
41
+ options.onBeginFrame?.(regions);
42
+ },
43
+ endFrame() {
44
+ options.onEndFrame?.();
45
+ const extra = options.extraLayers?.() ?? [];
46
+ const fullFrame = options.isFullFrame?.() ?? true;
47
+ gpu.render([layer, ...extra], {
48
+ regions: lastRegions.map((r) => ({
49
+ minX: r.x,
50
+ minY: r.y,
51
+ maxX: r.x + r.w,
52
+ maxY: r.y + r.h
53
+ })),
54
+ fullFrame
55
+ });
56
+ }
57
+ };
58
+ }
59
+ var GpuSceneNode = class extends SceneNode$1 {
60
+ paint(_layer) {
61
+ const root = this.gpuRoot();
62
+ if (!root) return;
63
+ this.drawSelf(root.layer);
64
+ for (const child of this.children) child.paint(void 0);
65
+ }
66
+ /** Walk the parent chain to the owning GpuSceneRoot, or null if detached. */
67
+ gpuRoot() {
68
+ let n = this;
69
+ while (n) {
70
+ if (n instanceof GpuSceneRoot) return n;
71
+ n = n.parent;
72
+ }
73
+ return null;
74
+ }
75
+ /** Mark a visual-only change: repaint, no data/layout rebuild. */
76
+ invalidatePaint(rect) {
77
+ this.markDamaged("paint", rect);
78
+ }
79
+ /** Mark a layout change (bounds/children moved). Triggers doLayout + paint. */
80
+ invalidateLayout(rect) {
81
+ this.markDamaged("layout", rect);
82
+ }
83
+ /** Mark a data change (inputs replaced). Triggers rebuildData → layout → paint. */
84
+ invalidateData(rect) {
85
+ this.markDamaged("data", rect);
86
+ }
87
+ };
88
+ var GpuSceneRoot = class extends SceneRoot$1 {
89
+ /** The scene layer that descendant nodes paint into. */
90
+ layer;
91
+ /** The underlying WebGPU renderer. */
92
+ gpu;
93
+ constructor(gpu, layer, options = {}) {
94
+ let self = null;
95
+ super(createLayerRenderer(gpu, layer, {
96
+ ...options,
97
+ isFullFrame: () => self?.fullFrame ?? true
98
+ }), options);
99
+ self = this;
100
+ this.gpu = gpu;
101
+ this.layer = layer;
102
+ this.fullFrame = options.fullFrame ?? true;
103
+ }
104
+ paint(_layer) {
105
+ for (const child of this.children) child.paint(void 0);
106
+ }
107
+ /**
108
+ * Force a full repaint on the next scheduled frame. Use when widget internals
109
+ * are mutated outside a damage-tracked setter; normal state changes mark their
110
+ * own damage and don't need this. (`setBounds` to the same rect is a no-op, so
111
+ * it can't be used for this.)
112
+ */
113
+ requestPaint() {
114
+ this._emitDamage({
115
+ rect: this.bounds,
116
+ kind: "paint"
117
+ });
118
+ }
119
+ };
120
+ //#endregion
121
+ export { DirtyChannel, GpuSceneNode, GpuSceneRoot, ManualScheduler, MicrotaskScheduler, PointerRouter, RAFScheduler, RectSpace, SceneNode, SceneRoot, Signal, SyncScheduler, createLayerRenderer, frameToRect, pointInRect, rectClamp, rectEquals, rectOf, rectOverlaps, rectToFrame, unionRects };
@@ -0,0 +1,185 @@
1
+ import { TgpuRoot } from "typegpu";
2
+ import { MsdfGlyph } from "insomni-msdf-text";
3
+
4
+ //#region src/core/root.d.ts
5
+ interface RootBacked {
6
+ device: GPUDevice;
7
+ root?: TgpuRoot;
8
+ }
9
+ type GPUOwner = GPUDevice | TgpuRoot | RootBacked;
10
+ declare function resolveRoot(owner: GPUOwner): TgpuRoot;
11
+ //#endregion
12
+ //#region src/shared/texture.d.ts
13
+ /** Borrowed sub-region of a caller-owned {@link Texture}. */
14
+ interface TextureRegion {
15
+ readonly texture: Texture;
16
+ readonly uvMin: readonly [number, number];
17
+ readonly uvMax: readonly [number, number];
18
+ }
19
+ /**
20
+ * Caller-owned GPU texture wrapper used by sprite APIs.
21
+ *
22
+ * `Layer`, `SpriteAtlas`, `GridAtlas`, and `Renderer2D` may retain references
23
+ * to a `Texture`, but none of them take ownership of it or destroy it on the caller's behalf.
24
+ */
25
+ declare class Texture {
26
+ readonly id: number;
27
+ readonly gpuTexture: GPUTexture;
28
+ readonly view: GPUTextureView;
29
+ readonly width: number;
30
+ readonly height: number;
31
+ private _destroyed;
32
+ constructor(gpuTexture: GPUTexture, width: number, height: number);
33
+ /** Sub-region by pixel coordinates. */
34
+ region(x: number, y: number, w: number, h: number): TextureRegion;
35
+ /** Sub-region by normalized UV coordinates. */
36
+ regionUV(u0: number, v0: number, u1: number, v1: number): TextureRegion;
37
+ get destroyed(): boolean;
38
+ /**
39
+ * Release the underlying GPU texture.
40
+ *
41
+ * Destroying a texture that is still referenced by a `Layer` is a caller error.
42
+ * Future sprite draws that still reference it will throw a clear runtime error.
43
+ */
44
+ destroy(): void;
45
+ private ensureAlive;
46
+ }
47
+ interface SpriteAtlasRegionDef {
48
+ x: number;
49
+ y: number;
50
+ w: number;
51
+ h: number;
52
+ }
53
+ declare class SpriteAtlas {
54
+ private readonly _regions;
55
+ constructor(texture: Texture, regions: Record<string, SpriteAtlasRegionDef>);
56
+ region(name: string): TextureRegion;
57
+ }
58
+ interface GridAtlasOptions {
59
+ /** Cell size in pixels [width, height]. */
60
+ cell: [number, number];
61
+ rows?: number;
62
+ cols?: number;
63
+ }
64
+ declare class GridAtlas {
65
+ private readonly texture;
66
+ private readonly cellW;
67
+ private readonly cellH;
68
+ private readonly cols;
69
+ private readonly rows;
70
+ constructor(texture: Texture, options: GridAtlasOptions);
71
+ /** Get a frame by linear index, or by (row, col). */
72
+ frame(indexOrRow: number, col?: number): TextureRegion;
73
+ }
74
+ interface LoadTextureOptions {
75
+ /** GPUTextureFormat for the created texture. Default: 'rgba8unorm'. */
76
+ format?: GPUTextureFormat;
77
+ label?: string;
78
+ }
79
+ /**
80
+ * Load a texture from a URL or any ImageBitmapSource.
81
+ * The result is in premultiplied alpha format, matching the renderer's blend state.
82
+ *
83
+ * The returned `Texture` remains caller-owned. The renderer may cache per-texture bind groups
84
+ * while it is in use, but it will never destroy the texture for you.
85
+ */
86
+ declare function loadTexture(owner: GPUOwner, src: string | ImageBitmapSource, options?: LoadTextureOptions): Promise<Texture>;
87
+ interface SamplerDescriptor {
88
+ /** Mag/min filter. Default: 'linear'. */
89
+ filter?: "linear" | "nearest";
90
+ /** UV addressing mode. Default: 'clamp-to-edge'. */
91
+ addressMode?: GPUAddressMode;
92
+ /** Mipmap filter. Default: 'linear'. */
93
+ mipmapFilter?: GPUMipmapFilterMode;
94
+ }
95
+ //#endregion
96
+ //#region src/text/text-font.d.ts
97
+ interface GlyphAtlasOptions {
98
+ /** Side length of the square atlas texture. Default 2048. */
99
+ atlasSize?: number;
100
+ /**
101
+ * Em size in atlas texels — the base resolution at which glyphs are
102
+ * rasterized. Larger = sharper rendering at high zoom, more atlas pressure.
103
+ * Default 64.
104
+ */
105
+ atlasFontSize?: number;
106
+ /**
107
+ * Distance range in atlas texels. Wider = thicker outlines / softer
108
+ * shadows but lower precision. Default 8.
109
+ */
110
+ pxRange?: number;
111
+ label?: string;
112
+ }
113
+ interface MeasureTextOptions {
114
+ fontSize: number;
115
+ maxWidth?: number;
116
+ lineHeight?: number;
117
+ fontFamily?: string;
118
+ fontWeight?: string | number;
119
+ fontStyle?: string;
120
+ /**
121
+ * Skip kerning, multi-line splits, and wrap. Pairs with the same flag on
122
+ * `TextShape` so a measured width matches what `pushText` will lay out.
123
+ */
124
+ simple?: boolean;
125
+ }
126
+ interface TextMetrics {
127
+ width: number;
128
+ height: number;
129
+ }
130
+ /**
131
+ * Common interface for both TTF (`Font`) and system (`RasterFont`) fonts.
132
+ *
133
+ * Em-relative metrics are normalized so the shaper works identically across
134
+ * kinds. Kerning is optional — `RasterFont` always returns 0.
135
+ */
136
+ interface TextFont {
137
+ readonly family: string;
138
+ readonly unitsPerEm: number;
139
+ /** Em-relative; positive Y up. */
140
+ readonly ascender: number;
141
+ /** Em-relative; negative. */
142
+ readonly descender: number;
143
+ /** Em-relative gap added between successive baselines. */
144
+ readonly lineGap: number;
145
+ getKerning(left: number, right: number): number;
146
+ }
147
+ /**
148
+ * Glyph atlas — owns the GPU atlas texture and lazily rasterizes glyphs on
149
+ * first request. Both MSDF (TTF) and SDF (raster) implementations satisfy
150
+ * this interface.
151
+ */
152
+ interface GlyphAtlas {
153
+ readonly font: TextFont;
154
+ readonly pxRange: number;
155
+ readonly atlasFontSize: number;
156
+ readonly atlasSize: number;
157
+ readonly texture: Texture;
158
+ readonly glyphCount: number;
159
+ readonly destroyed: boolean;
160
+ /** Approximate fill percentage based on shelf cursor position. */
161
+ readonly fillPercent: number;
162
+ /**
163
+ * Monotonic counter incremented every time a new glyph is allocated.
164
+ * External GPU mirrors of the atlas (e.g. a metrics LUT) compare against
165
+ * a stored value to detect when a re-sync is needed.
166
+ */
167
+ readonly version: number;
168
+ /**
169
+ * Return the glyph entry for `codepoint`, generating it on first request.
170
+ * Returns null when the font lacks the glyph or the atlas is full.
171
+ */
172
+ getGlyph(codepoint: number): MsdfGlyph | null;
173
+ /**
174
+ * Fetch a glyph by its `atlasGlyphId` (the sequential id assigned at
175
+ * allocation time). Returns `undefined` for unknown ids. Used by GPU
176
+ * mirrors to walk newly added entries on sync.
177
+ */
178
+ getGlyphById(id: number): MsdfGlyph | undefined;
179
+ measureText(text: string, options: MeasureTextOptions): TextMetrics;
180
+ /** Pre-generate a string of glyphs. Useful for warming the atlas at startup. */
181
+ preload(text: string): void;
182
+ destroy(): void;
183
+ }
184
+ //#endregion
185
+ export { resolveRoot as _, TextMetrics as a, GridAtlasOptions as c, SpriteAtlas as d, SpriteAtlasRegionDef as f, GPUOwner as g, loadTexture as h, TextFont as i, LoadTextureOptions as l, TextureRegion as m, GlyphAtlasOptions as n, MsdfGlyph as o, Texture as p, MeasureTextOptions as r, GridAtlas as s, GlyphAtlas as t, SamplerDescriptor as u };
@@ -0,0 +1,91 @@
1
+ import { a as TextMetrics, g as GPUOwner, n as GlyphAtlasOptions, o as MsdfGlyph, p as Texture, r as MeasureTextOptions, t as GlyphAtlas } from "./text-font-D7GGDtTK.mjs";
2
+ import { Font, Font as Font$1, FontOptions, FontSource, loadFont, parseFont } from "insomni-msdf-text";
3
+
4
+ //#region src/text/msdf-adapter.d.ts
5
+ declare class MsdfGlyphAtlas implements GlyphAtlas {
6
+ readonly font: Font$1;
7
+ private readonly _atlas;
8
+ private readonly _texture;
9
+ private measureCache;
10
+ private measureCacheVersion;
11
+ constructor(owner: GPUOwner, font: Font$1, options?: GlyphAtlasOptions);
12
+ get pxRange(): number;
13
+ get atlasFontSize(): number;
14
+ get atlasSize(): number;
15
+ get texture(): Texture;
16
+ get glyphCount(): number;
17
+ get destroyed(): boolean;
18
+ get fillPercent(): number;
19
+ get version(): number;
20
+ getGlyph(codepoint: number): MsdfGlyph | null;
21
+ getGlyphById(id: number): MsdfGlyph | undefined;
22
+ measureText(text: string, options: MeasureTextOptions): TextMetrics;
23
+ preload(text: string): void;
24
+ destroy(): void;
25
+ }
26
+ //#endregion
27
+ //#region src/text/cpu-glyph-atlas.d.ts
28
+ declare class CpuGlyphAtlas implements GlyphAtlas {
29
+ readonly font: Font$1;
30
+ readonly pxRange: number;
31
+ readonly atlasFontSize: number;
32
+ readonly atlasSize: number;
33
+ private readonly cache;
34
+ /** Glyphs indexed by `atlasGlyphId`. Append-only; mirrors MsdfGlyphAtlas. */
35
+ private readonly _glyphList;
36
+ /** Bumps every time `_glyphList` grows. */
37
+ private _version;
38
+ private readonly measureCache;
39
+ private _destroyed;
40
+ constructor(font: Font$1, options?: GlyphAtlasOptions);
41
+ get version(): number;
42
+ get glyphCount(): number;
43
+ get destroyed(): boolean;
44
+ /** Always 0 — no shelf packer needed (no texture). */
45
+ get fillPercent(): number;
46
+ /**
47
+ * CPU atlas has no GPU texture. Throws if accessed so misuse is loud, not
48
+ * silent corruption. The SVG renderer never reads `texture` — it gates on
49
+ * `layer.atlas` and decodes via `getGlyphById` (`svg-renderer.ts:285`).
50
+ */
51
+ get texture(): Texture;
52
+ /**
53
+ * Return the glyph entry for `codepoint`, computing metrics from the font
54
+ * outline on first request. UVs are set to 0 (no texture).
55
+ *
56
+ * Mirrors `MsdfGlyphAtlas.getGlyph` (atlas.ts:133-232) with the
57
+ * shelf-packer, `generate()`, and UV-from-origin math removed.
58
+ */
59
+ getGlyph(codepoint: number): MsdfGlyph | null;
60
+ /**
61
+ * Fetch a glyph by its `atlasGlyphId` (allocation order). O(1) array lookup.
62
+ * This is the decode contract: `svg-renderer.ts:512` calls this to reconstruct
63
+ * the original codepoint from a glyph-pack instance.
64
+ */
65
+ getGlyphById(id: number): MsdfGlyph | undefined;
66
+ /**
67
+ * Verbatim copy of `msdf-adapter.ts:75-109` — depends only on `this.font`
68
+ * and `this` as the GlyphAtlas shaper arg (no GPU involvement).
69
+ */
70
+ measureText(text: string, options: MeasureTextOptions): TextMetrics;
71
+ /** Pre-warm the glyph cache for a string of text. No GPU work. */
72
+ preload(text: string): void;
73
+ /** Clear caches and mark as destroyed. */
74
+ destroy(): void;
75
+ }
76
+ declare function sharedCpuGlyphAtlas(): CpuGlyphAtlas;
77
+ /**
78
+ * Create a non-singleton `CpuGlyphAtlas`, optionally with a custom font.
79
+ *
80
+ * - Pass `font` (an already-parsed `Font`) for zero-overhead construction.
81
+ * - Pass `fontBytes` (ArrayBuffer or Uint8Array) to parse on construction.
82
+ * - Pass neither to fall back to the embedded Lato subset (same font as the
83
+ * shared singleton, but a fresh atlas instance).
84
+ */
85
+ declare function createCpuGlyphAtlas(opts?: {
86
+ font?: Font$1;
87
+ fontBytes?: ArrayBuffer | Uint8Array;
88
+ options?: GlyphAtlasOptions;
89
+ }): CpuGlyphAtlas;
90
+ //#endregion
91
+ export { CpuGlyphAtlas, Font, type FontOptions, type FontSource, MsdfGlyphAtlas, createCpuGlyphAtlas, loadFont, parseFont, sharedCpuGlyphAtlas };