@vectojs/core 1.14.0 → 1.15.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.
- package/dist/{chunk-XIEQHSBB.mjs → chunk-64UFEHOJ.mjs} +7 -464
- package/dist/{chunk-2Z23LTH3.js → chunk-J6NHSFIE.js} +60 -517
- package/dist/index.d.ts +4 -12
- package/dist/index.js +58 -178
- package/dist/index.mjs +12 -132
- package/dist/layout/index.d.ts +1 -3
- package/dist/layout.js +2 -16
- package/dist/layout.mjs +2 -16
- package/dist/text/MSDFTextEntity.d.ts +1 -1
- package/dist/text/index.d.ts +1 -5
- package/dist/text.js +5 -16
- package/dist/text.mjs +6 -17
- package/dist/tree/Entity.d.ts +2 -2
- package/package.json +8 -6
- package/dist/animation/drivers.d.ts +0 -48
- package/dist/animation/easing.d.ts +0 -16
- package/dist/chunk-4AR425AR.js +0 -1121
- package/dist/chunk-BA5HUUDF.js +0 -760
- package/dist/chunk-IESDTEJ4.mjs +0 -1121
- package/dist/chunk-X7I465AQ.mjs +0 -760
- package/dist/layout/LayoutEngine.d.ts +0 -289
- package/dist/layout/LayoutWorker.d.ts +0 -23
- package/dist/layout/LayoutWorkerManager.d.ts +0 -26
- package/dist/layout/LayoutWorkerSource.d.ts +0 -1
- package/dist/layout/measure.d.ts +0 -20
- package/dist/math/SpatialHashGrid.d.ts +0 -53
- package/dist/math/SpringPhysics.d.ts +0 -13
- package/dist/text/ArabicShaper.d.ts +0 -10
- package/dist/text/BidiResolver.d.ts +0 -5
- package/dist/text/MSDFFont.d.ts +0 -129
- package/dist/text/PreparedContentGrid.d.ts +0 -60
- package/dist/text/Typography.d.ts +0 -11
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Map from a single grapheme character to its pre-measured glyph metrics.
|
|
3
|
-
*
|
|
4
|
-
* Each entry provides the glyph's pixel `width` at `baseSize`, and an `ast`
|
|
5
|
-
* property holding the raw vector path data used by the renderer.
|
|
6
|
-
*/
|
|
7
|
-
export interface GlyphAtlas {
|
|
8
|
-
[char: string]: {
|
|
9
|
-
width: number;
|
|
10
|
-
baseSize: number;
|
|
11
|
-
ast: any;
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Resolves the pixel advance width of a single grapheme at a given font size,
|
|
16
|
-
* for glyphs not present in a pre-baked {@link GlyphAtlas}.
|
|
17
|
-
*
|
|
18
|
-
* Implemented by {@link createCanvasMeasurer} (canvas `measureText`), but kept
|
|
19
|
-
* abstract so callers can supply their own metrics source.
|
|
20
|
-
*/
|
|
21
|
-
export interface GlyphMeasurer {
|
|
22
|
-
measure(char: string, fontSize: number): number;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Per-run inline style for rich text ({@link LayoutEngine.prepareRich}). All
|
|
26
|
-
* fields are optional and inherited from the call's base style when omitted.
|
|
27
|
-
*/
|
|
28
|
-
export interface TextStyle {
|
|
29
|
-
/** Font size in px for this run; overrides the base size (affects width + line height). */
|
|
30
|
-
fontSize?: number;
|
|
31
|
-
/** Fill color, e.g. `'#38bdf8'`. */
|
|
32
|
-
color?: string;
|
|
33
|
-
/** Bold weight (rendering only; width still measured at base metrics). */
|
|
34
|
-
bold?: boolean;
|
|
35
|
-
/** Italic slant (rendering only). */
|
|
36
|
-
italic?: boolean;
|
|
37
|
-
/** Hyperlink destination; carried through to the positioned nodes for hit-testing / a11y. */
|
|
38
|
-
href?: string;
|
|
39
|
-
}
|
|
40
|
-
/** A run of text sharing one {@link TextStyle}, the input unit of {@link LayoutEngine.prepareRich}. */
|
|
41
|
-
export interface StyledSpan {
|
|
42
|
-
text: string;
|
|
43
|
-
style?: TextStyle;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* A single positioned glyph produced by {@link LayoutEngine.layoutText}.
|
|
47
|
-
*/
|
|
48
|
-
export interface LayoutNode {
|
|
49
|
-
char: string;
|
|
50
|
-
x: number;
|
|
51
|
-
y: number;
|
|
52
|
-
width: number;
|
|
53
|
-
height: number;
|
|
54
|
-
/** Inline style carried from rich text; `undefined` for plain (single-style) layout. */
|
|
55
|
-
style?: TextStyle;
|
|
56
|
-
sourceIndex?: number;
|
|
57
|
-
sourceLength?: number;
|
|
58
|
-
isRTL?: boolean;
|
|
59
|
-
combining?: string[];
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* The complete output of a text layout pass — an ordered list of positioned
|
|
63
|
-
* glyphs and the total bounding-box dimensions.
|
|
64
|
-
*/
|
|
65
|
-
export interface LayoutResult {
|
|
66
|
-
nodes: LayoutNode[];
|
|
67
|
-
totalWidth: number;
|
|
68
|
-
totalHeight: number;
|
|
69
|
-
fallbackToCanvas?: boolean;
|
|
70
|
-
}
|
|
71
|
-
/** A single measured grapheme (the "cold" half of the cold/hot split). */
|
|
72
|
-
export interface PreparedGlyph {
|
|
73
|
-
char: string;
|
|
74
|
-
/** Advance width at the prepared `fontSize`. */
|
|
75
|
-
width: number;
|
|
76
|
-
/** Inline style (rich text only); drives per-glyph size, color and baseline. */
|
|
77
|
-
style?: TextStyle;
|
|
78
|
-
level: number;
|
|
79
|
-
sourceIndex: number;
|
|
80
|
-
sourceLength: number;
|
|
81
|
-
combining?: string[];
|
|
82
|
-
}
|
|
83
|
-
/** A measured word/segment, ready to be placed without re-measuring. */
|
|
84
|
-
export interface PreparedWord {
|
|
85
|
-
glyphs: PreparedGlyph[];
|
|
86
|
-
/** Sum of glyph advances — used for word-level wrap decisions. */
|
|
87
|
-
width: number;
|
|
88
|
-
isWordLike: boolean | undefined;
|
|
89
|
-
/** Pre-computed `word.trim().length === 0`. */
|
|
90
|
-
isWhitespace: boolean;
|
|
91
|
-
/**
|
|
92
|
-
* Glyph indices where the word may break with a visible hyphen — from
|
|
93
|
-
* soft hyphens (U+00AD) in the source or the engine's `hyphenate` hook.
|
|
94
|
-
*/
|
|
95
|
-
breakPoints?: number[];
|
|
96
|
-
}
|
|
97
|
-
/** A measured paragraph; `isEmpty` marks a blank line (forced newline). */
|
|
98
|
-
export interface PreparedParagraph {
|
|
99
|
-
words: PreparedWord[];
|
|
100
|
-
isEmpty: boolean;
|
|
101
|
-
fallbackToCanvas?: boolean;
|
|
102
|
-
baseLevel?: number;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* The result of the **cold** measurement pass ({@link LayoutEngine.prepare}):
|
|
106
|
-
* segmented + measured text that is independent of layout constraints
|
|
107
|
-
* (`maxWidth`/`maxHeight`/exclusion masks). Reuse it across cheap **hot**
|
|
108
|
-
* re-layouts ({@link LayoutEngine.layoutPrepared}) on resize / reposition,
|
|
109
|
-
* avoiding the per-frame `Intl.Segmenter` + measurement cost.
|
|
110
|
-
*/
|
|
111
|
-
export interface PreparedText {
|
|
112
|
-
paragraphs: PreparedParagraph[];
|
|
113
|
-
fontSize: number;
|
|
114
|
-
fallbackToCanvas?: boolean;
|
|
115
|
-
/** Advance width of '-' at `fontSize`, for wrap-time hyphen insertion. */
|
|
116
|
-
hyphenWidth?: number;
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* A rectangular region (in the text's local coordinate space) that text must
|
|
120
|
-
* flow around — the v1 of text flow exclusion shapes. A left/right rect acts
|
|
121
|
-
* like a CSS float; a centered rect splits the affected lines in two.
|
|
122
|
-
*/
|
|
123
|
-
export interface ExclusionRect {
|
|
124
|
-
x: number;
|
|
125
|
-
y: number;
|
|
126
|
-
width: number;
|
|
127
|
-
height: number;
|
|
128
|
-
}
|
|
129
|
-
/** A free horizontal interval `[x0, x1)` available for text on one line. */
|
|
130
|
-
export interface LineSegment {
|
|
131
|
-
x0: number;
|
|
132
|
-
x1: number;
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* The free horizontal segments left in `[0, maxWidth]` for a line whose box
|
|
136
|
-
* spans the vertical band `[top, bottom)`, after subtracting every
|
|
137
|
-
* {@link ExclusionRect} that overlaps that band. Returns the full width when
|
|
138
|
-
* nothing overlaps, and `[]` when an exclusion (or union of them) spans the
|
|
139
|
-
* whole width. Pure — the testable core of exclusion flow.
|
|
140
|
-
*
|
|
141
|
-
* Time O(n log n) in the number of overlapping exclusions; space O(n).
|
|
142
|
-
*/
|
|
143
|
-
export declare function computeLineSegments(top: number, bottom: number, maxWidth: number, exclusions: ExclusionRect[]): LineSegment[];
|
|
144
|
-
/**
|
|
145
|
-
* VectoJS Global Layout Engine (Intl.Segmenter)
|
|
146
|
-
* Advanced Typography Engine supporting CJK, Emoji, and Western Graphemes
|
|
147
|
-
*/
|
|
148
|
-
export declare class LayoutEngine {
|
|
149
|
-
maxWidth: number;
|
|
150
|
-
/**
|
|
151
|
-
* Horizontal alignment. `'justify'` stretches inter-word spaces (or, for
|
|
152
|
-
* space-less CJK lines, inter-character gaps) so wrapped lines end flush at
|
|
153
|
-
* `maxWidth`; the last line of each paragraph stays ragged. Only applies to
|
|
154
|
-
* the object layout path without exclusion shapes.
|
|
155
|
-
*/
|
|
156
|
-
textAlign: 'left' | 'justify';
|
|
157
|
-
maxHeight: number;
|
|
158
|
-
preserveLeadingSpaces: boolean;
|
|
159
|
-
private wordSegmenter;
|
|
160
|
-
private charSegmenter;
|
|
161
|
-
private wordCache;
|
|
162
|
-
private graphemeCache;
|
|
163
|
-
private paragraphCache;
|
|
164
|
-
private richParagraphCache;
|
|
165
|
-
private lastAtlas;
|
|
166
|
-
private measurer;
|
|
167
|
-
private _hyphenate;
|
|
168
|
-
/**
|
|
169
|
-
* Optional hyphenator: given a word, return its break parts (e.g.
|
|
170
|
-
* `['hyphen', 'ation']`). Used at wrap time when a word doesn't fit; a
|
|
171
|
-
* visible '-' is drawn at the chosen break. Soft hyphens (U+00AD) in the
|
|
172
|
-
* source work without any hyphenator. Setting this clears the prepared
|
|
173
|
-
* caches (break opportunities are baked in during prepare()).
|
|
174
|
-
*/
|
|
175
|
-
get hyphenate(): ((word: string) => string[]) | null;
|
|
176
|
-
set hyphenate(fn: ((word: string) => string[]) | null);
|
|
177
|
-
constructor(maxWidth: number, maxHeight: number, measurer?: GlyphMeasurer | null);
|
|
178
|
-
private getWordSegments;
|
|
179
|
-
/**
|
|
180
|
-
* Resolve a grapheme's advance width at `fontSize`, in priority order:
|
|
181
|
-
* pre-baked atlas entry → injected {@link GlyphMeasurer} → `0.5em` fallback.
|
|
182
|
-
*/
|
|
183
|
-
private glyphWidth;
|
|
184
|
-
private glyphKeyFor;
|
|
185
|
-
private getGraphemes;
|
|
186
|
-
/**
|
|
187
|
-
* Lay out a Unicode string into a list of positioned {@link LayoutNode} glyphs.
|
|
188
|
-
*
|
|
189
|
-
* Uses `Intl.Segmenter` to correctly handle CJK, emoji, and Western word
|
|
190
|
-
* boundaries. An optional `exclusionMask` callback allows glyphs to flow
|
|
191
|
-
* around arbitrary shapes (e.g. physics bodies or video regions).
|
|
192
|
-
*
|
|
193
|
-
* @param text - The raw text string to lay out (newlines force paragraph breaks).
|
|
194
|
-
* @param fontAtlas - Pre-measured glyph metrics keyed by grapheme character.
|
|
195
|
-
* @param fontSize - Target font size in pixels (default: `32`).
|
|
196
|
-
* @param exclusionMask - Optional callback returning `true` when a candidate
|
|
197
|
-
* glyph bounding box overlaps a forbidden region; the engine skips that
|
|
198
|
-
* position and advances horizontally.
|
|
199
|
-
* @returns A {@link LayoutResult} with all positioned glyph nodes and total dimensions.
|
|
200
|
-
* @example
|
|
201
|
-
* const result = engine.layoutText('Hello 世界', atlas, 24);
|
|
202
|
-
* result.nodes.forEach(n => console.log(n.char, n.x, n.y));
|
|
203
|
-
*/
|
|
204
|
-
layoutText(text: string, fontAtlas: GlyphAtlas, fontSize?: number, exclusionMask?: (x: number, y: number, w: number, h: number) => boolean): LayoutResult;
|
|
205
|
-
/**
|
|
206
|
-
* **Cold pass.** Segment and measure `text` once into a reusable
|
|
207
|
-
* {@link PreparedText}. Runs `Intl.Segmenter` (word + grapheme) and resolves
|
|
208
|
-
* each grapheme's advance width — the expensive work. The result is
|
|
209
|
-
* independent of `maxWidth`/`maxHeight`/exclusion masks, so it can be re-laid
|
|
210
|
-
* out cheaply by {@link layoutPrepared} on resize / reposition / animation.
|
|
211
|
-
*
|
|
212
|
-
* @param text - The raw text string (newlines force paragraph breaks).
|
|
213
|
-
* @param fontAtlas - Pre-measured glyph metrics keyed by grapheme character.
|
|
214
|
-
* @param fontSize - Target font size in pixels (default: `32`).
|
|
215
|
-
*/
|
|
216
|
-
prepare(text: string, fontAtlas: GlyphAtlas, fontSize?: number): PreparedText;
|
|
217
|
-
/**
|
|
218
|
-
* **Cold pass for rich text.** Like {@link prepare}, but takes an array of
|
|
219
|
-
* {@link StyledSpan}s so different inline runs (bold / italic / color / size /
|
|
220
|
-
* links) compose on the same wrapped lines. Each grapheme carries the
|
|
221
|
-
* (base-merged) style of the span it came from — so a style change *mid-word*
|
|
222
|
-
* (e.g. `He` + **`llo`**) is honored. Run `fontSize` affects measured width and
|
|
223
|
-
* line height; the rest is rendering metadata carried through to the nodes.
|
|
224
|
-
*
|
|
225
|
-
* The result feeds the same {@link layoutPrepared} as plain text.
|
|
226
|
-
*
|
|
227
|
-
* @param spans - The styled runs, in document order.
|
|
228
|
-
* @param fontAtlas - Pre-measured glyph metrics keyed by grapheme character.
|
|
229
|
-
* @param baseFontSize - Size for runs without an explicit `fontSize` (default 32).
|
|
230
|
-
* @param baseStyle - Style inherited by every run (each run's own style wins).
|
|
231
|
-
*/
|
|
232
|
-
prepareRich(spans: StyledSpan[], fontAtlas: GlyphAtlas, baseFontSize?: number, baseStyle?: TextStyle): PreparedText;
|
|
233
|
-
/**
|
|
234
|
-
* **Hot pass.** Place an already-measured {@link PreparedText} into positioned
|
|
235
|
-
* glyphs. Does only wrap/positioning arithmetic — no `Intl.Segmenter`, no
|
|
236
|
-
* re-measurement — so it is cheap enough to call every frame or on every
|
|
237
|
-
* resize. Reads the engine's current `maxWidth`/`maxHeight`, so changing those
|
|
238
|
-
* and re-calling reflows the same prepared text.
|
|
239
|
-
*
|
|
240
|
-
* @param prepared - Output of {@link prepare}.
|
|
241
|
-
* @param exclusionMask - Optional per-glyph collision callback (see {@link layoutText}).
|
|
242
|
-
* @param exclusions - Optional rect regions text flows around (exclusion shapes); each
|
|
243
|
-
* line is split into the free x-segments left after subtracting them. Omitting
|
|
244
|
-
* it (or passing `[]`) leaves the single-column path byte-for-byte unchanged.
|
|
245
|
-
*/
|
|
246
|
-
layoutPrepared(prepared: PreparedText, exclusionMask?: (x: number, y: number, w: number, h: number) => boolean, exclusions?: ExclusionRect[]): LayoutResult;
|
|
247
|
-
/**
|
|
248
|
-
* Lay out a Unicode string directly into a pre-allocated {@link LayoutResultBuffer}.
|
|
249
|
-
*
|
|
250
|
-
* Avoids GC allocations by writing results directly to flat typed arrays in the buffer.
|
|
251
|
-
*
|
|
252
|
-
* @param text - The raw text string to lay out.
|
|
253
|
-
* @param fontAtlas - Pre-measured glyph metrics keyed by grapheme character.
|
|
254
|
-
* @param fontSize - Target font size in pixels.
|
|
255
|
-
* @param buffer - The pre-allocated buffer to write layout results into.
|
|
256
|
-
* @param exclusionMask - Optional collision-detection callback.
|
|
257
|
-
*/
|
|
258
|
-
layoutTextIntoBuffer(text: string, fontAtlas: GlyphAtlas, fontSize: number, buffer: LayoutResultBuffer, exclusionMask?: (x: number, y: number, w: number, h: number) => boolean): void;
|
|
259
|
-
/**
|
|
260
|
-
* **Hot pass, zero-GC variant.** Place an already-measured {@link PreparedText}
|
|
261
|
-
* directly into a pre-allocated {@link LayoutResultBuffer}. Like
|
|
262
|
-
* {@link layoutPrepared} but writes flat typed arrays instead of allocating
|
|
263
|
-
* {@link LayoutNode} objects — the per-frame path for large dynamic scenes.
|
|
264
|
-
*/
|
|
265
|
-
layoutPreparedIntoBuffer(prepared: PreparedText, buffer: LayoutResultBuffer, exclusionMask?: (x: number, y: number, w: number, h: number) => boolean): void;
|
|
266
|
-
}
|
|
267
|
-
/**
|
|
268
|
-
* Pre-allocated buffer for zero-GC layout results.
|
|
269
|
-
* Reuse a single instance across frames by calling reset() before each layout pass.
|
|
270
|
-
*/
|
|
271
|
-
export declare class LayoutResultBuffer {
|
|
272
|
-
static readonly CAPACITY = 16384;
|
|
273
|
-
/** X positions of each glyph. */
|
|
274
|
-
xs: Float32Array;
|
|
275
|
-
/** Y positions of each glyph. */
|
|
276
|
-
ys: Float32Array;
|
|
277
|
-
/** Widths of each glyph. */
|
|
278
|
-
ws: Float32Array;
|
|
279
|
-
/** Heights of each glyph. */
|
|
280
|
-
hs: Float32Array;
|
|
281
|
-
/** Character for each glyph slot. */
|
|
282
|
-
chars: string[];
|
|
283
|
-
/** Number of valid glyphs written in this buffer. */
|
|
284
|
-
count: number;
|
|
285
|
-
/** Reset the buffer for reuse. Does NOT free memory. */
|
|
286
|
-
reset(): void;
|
|
287
|
-
/** Convert to the standard LayoutResult format (allocates — use sparingly). */
|
|
288
|
-
toLayoutResult(): LayoutResult;
|
|
289
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { MSDFFontData } from '../text/MSDFFont';
|
|
2
|
-
export interface LayoutWorkerRequest {
|
|
3
|
-
id: string;
|
|
4
|
-
seqId: number;
|
|
5
|
-
text: string;
|
|
6
|
-
fontId: string;
|
|
7
|
-
fontData?: MSDFFontData;
|
|
8
|
-
maxWidth: number;
|
|
9
|
-
maxHeight: number;
|
|
10
|
-
fontSize: number;
|
|
11
|
-
lineHeight?: number;
|
|
12
|
-
letterSpacing?: number;
|
|
13
|
-
}
|
|
14
|
-
export interface LayoutWorkerResponse {
|
|
15
|
-
id: string;
|
|
16
|
-
seqId: number;
|
|
17
|
-
width: number;
|
|
18
|
-
height: number;
|
|
19
|
-
codePoints: Uint32Array;
|
|
20
|
-
xCoords: Float32Array;
|
|
21
|
-
yCoords: Float32Array;
|
|
22
|
-
packedStyles: Uint32Array;
|
|
23
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { LayoutWorkerResponse } from './LayoutWorker';
|
|
2
|
-
export declare class LayoutWorkerManager {
|
|
3
|
-
private static instance;
|
|
4
|
-
private worker;
|
|
5
|
-
private registeredFonts;
|
|
6
|
-
private pendingCallbacks;
|
|
7
|
-
private seqIdCounter;
|
|
8
|
-
private debounceTimers;
|
|
9
|
-
private constructor();
|
|
10
|
-
private createWorker;
|
|
11
|
-
private ensureWorker;
|
|
12
|
-
private handleWorkerFailure;
|
|
13
|
-
destroy(): void;
|
|
14
|
-
static getInstance(): LayoutWorkerManager;
|
|
15
|
-
queueLayout(entityId: string, text: string, options: {
|
|
16
|
-
fontId: string;
|
|
17
|
-
fontSize: number;
|
|
18
|
-
maxWidth: number;
|
|
19
|
-
maxHeight: number;
|
|
20
|
-
fontData?: any;
|
|
21
|
-
lineHeight?: number;
|
|
22
|
-
letterSpacing?: number;
|
|
23
|
-
callback: (res: LayoutWorkerResponse) => void;
|
|
24
|
-
}): void;
|
|
25
|
-
cancelLayout(entityId: string): void;
|
|
26
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const WORKER_SOURCE_STRING = "\"use strict\";(()=>{var C=new Map;function f(t){return typeof t==\"number\"&&Number.isFinite(t)}function U(t){return t.origin?t.origin===self.location.origin:!0}function j(t){if(!t||typeof t!=\"object\")return!1;let e=t;return typeof e.id==\"string\"&&f(e.seqId)&&typeof e.text==\"string\"&&typeof e.fontId==\"string\"&&(e.fontData===void 0||typeof e.fontData==\"object\")&&f(e.maxWidth)&&f(e.maxHeight)&&f(e.fontSize)&&(e.lineHeight===void 0||f(e.lineHeight))&&(e.letterSpacing===void 0||f(e.letterSpacing))}self.onmessage=t=>{if(!U(t)||!j(t.data))return;let{id:e,seqId:D,text:L,fontId:k,fontData:S,maxWidth:H,maxHeight:z,fontSize:d,lineHeight:I,letterSpacing:M}=t.data;S&&C.set(k,S);let g=C.get(k);if(!g)return;let m=[],i=[],h=[],w=[],n=0,c=0,r=0,o=-1,p=g.metrics?.ascender??.8,R=g.metrics?.descender??-.2,b=I??d*(p-R),P=M??0,F=new Map;for(let s of g.glyphs??[])F.set(s.unicode,s.advance);let x=()=>{n>r&&(r=n),n=0,c++,o=-1},A=Array.from(L);for(let s=0;s<A.length;s++){let a=A[s].codePointAt(0);if(a===10){x();continue}let W=(F.get(a)??1)*d,q=a>=11904;if(q&&(o=-1),n+W>H&&n>0){if(a===32){x();continue}if(o>=0&&i[o]>0){let l=i[o];l>r&&(r=l),c++;let v=c*b+p*d;for(let y=o;y<i.length;y++)i[y]-=l,h[y]=v;n-=l}else x()}a===32?o=-1:o===-1&&!q&&(o=m.length),m.push(a),i.push(n),h.push(c*b+p*d),w.push(-256),n+=W+P}n>r&&(r=n);let u={id:e,seqId:D,width:r,height:(c+1)*b,codePoints:new Uint32Array(m),xCoords:new Float32Array(i),yCoords:new Float32Array(h),packedStyles:new Uint32Array(w)};self.postMessage(u,[u.codePoints.buffer,u.xCoords.buffer,u.yCoords.buffer,u.packedStyles.buffer])};})();\n";
|
package/dist/layout/measure.d.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import type { GlyphMeasurer } from './LayoutEngine';
|
|
2
|
-
/**
|
|
3
|
-
* Create a {@link GlyphMeasurer} backed by a single lazily-created offscreen
|
|
4
|
-
* Canvas 2D context.
|
|
5
|
-
*
|
|
6
|
-
* Each grapheme is measured once at `baseSize` and cached; because canvas
|
|
7
|
-
* `measureText` advance width is linear in font size, later queries at any
|
|
8
|
-
* `fontSize` are derived by pure arithmetic (no re-measure). This gives the
|
|
9
|
-
* {@link LayoutEngine} real per-glyph metrics for text that has no pre-baked
|
|
10
|
-
* vector atlas, fixing the coarse `0.5em` line-breaking fallback.
|
|
11
|
-
*
|
|
12
|
-
* Returns `null` in DOM-free environments (SSR, workers without a canvas) so
|
|
13
|
-
* callers stay portable and the engine keeps its `0.5em` fallback.
|
|
14
|
-
*
|
|
15
|
-
* @param fontFamily - CSS font family used for measurement; should match what
|
|
16
|
-
* the renderer actually draws (e.g. `TextEntity` falls back to `sans-serif`).
|
|
17
|
-
* @param baseSize - Pixel size at which each glyph is measured and cached.
|
|
18
|
-
* @returns A measurer, or `null` when no Canvas 2D context is available.
|
|
19
|
-
*/
|
|
20
|
-
export declare function createCanvasMeasurer(fontFamily?: string, baseSize?: number): GlyphMeasurer | null;
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fixed-cell Spatial Hash Grid for O(1) average-case AABB neighbor queries.
|
|
3
|
-
* Insert entities each frame, then query by AABB to find nearby entity IDs.
|
|
4
|
-
*/
|
|
5
|
-
export declare class SpatialHashGrid {
|
|
6
|
-
private cellSize;
|
|
7
|
-
private grid;
|
|
8
|
-
private entityCells;
|
|
9
|
-
constructor(cellSize?: number);
|
|
10
|
-
private hash;
|
|
11
|
-
private cellsForAABB;
|
|
12
|
-
/**
|
|
13
|
-
* Insert or update an entity's axis-aligned bounding box in the grid.
|
|
14
|
-
*
|
|
15
|
-
* If the entity is already registered its old cell memberships are removed
|
|
16
|
-
* before the new ones are computed, so this method is safe to call every
|
|
17
|
-
* frame.
|
|
18
|
-
*
|
|
19
|
-
* @param id - Unique string identifier for the entity.
|
|
20
|
-
* @param x - Left edge of the AABB in world space.
|
|
21
|
-
* @param y - Top edge of the AABB in world space.
|
|
22
|
-
* @param w - Width of the AABB.
|
|
23
|
-
* @param h - Height of the AABB.
|
|
24
|
-
*/
|
|
25
|
-
insert(id: string, x: number, y: number, w: number, h: number): void;
|
|
26
|
-
/**
|
|
27
|
-
* Remove an entity from all grid cells it currently occupies.
|
|
28
|
-
*
|
|
29
|
-
* Silently does nothing if the entity is not registered.
|
|
30
|
-
*
|
|
31
|
-
* @param id - Unique string identifier of the entity to remove.
|
|
32
|
-
*/
|
|
33
|
-
remove(id: string): void;
|
|
34
|
-
/**
|
|
35
|
-
* Return all entity IDs whose grid cells overlap the given AABB.
|
|
36
|
-
*
|
|
37
|
-
* Time complexity: O(k) where k is the number of cells the query AABB spans
|
|
38
|
-
* plus the number of results — O(1) average for small, similarly-sized entities.
|
|
39
|
-
*
|
|
40
|
-
* @param x - Left edge of the query AABB.
|
|
41
|
-
* @param y - Top edge of the query AABB.
|
|
42
|
-
* @param w - Width of the query AABB.
|
|
43
|
-
* @param h - Height of the query AABB.
|
|
44
|
-
* @returns A `Set` of entity ID strings whose cells intersect the query region.
|
|
45
|
-
*/
|
|
46
|
-
query(x: number, y: number, w: number, h: number): Set<string>;
|
|
47
|
-
/**
|
|
48
|
-
* Clear all cells and entity registrations, resetting the grid to an empty state.
|
|
49
|
-
*
|
|
50
|
-
* Call once per frame before re-inserting all dynamic entities.
|
|
51
|
-
*/
|
|
52
|
-
clear(): void;
|
|
53
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export declare class SpringPhysics {
|
|
2
|
-
value: number;
|
|
3
|
-
target: number;
|
|
4
|
-
velocity: number;
|
|
5
|
-
stiffness: number;
|
|
6
|
-
damping: number;
|
|
7
|
-
mass: number;
|
|
8
|
-
private readonly valEpsilon;
|
|
9
|
-
private readonly velEpsilon;
|
|
10
|
-
constructor(initial: number);
|
|
11
|
-
update(dt: number): void;
|
|
12
|
-
isAtRest(): boolean;
|
|
13
|
-
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export interface ShapedResult {
|
|
2
|
-
shapedText: string;
|
|
3
|
-
indexMap: Int32Array;
|
|
4
|
-
}
|
|
5
|
-
export declare class ArabicShaper {
|
|
6
|
-
private static MAPPINGS;
|
|
7
|
-
private static isHarakat;
|
|
8
|
-
private static getJoiningType;
|
|
9
|
-
static shapeArabic(text: string): ShapedResult;
|
|
10
|
-
}
|
package/dist/text/MSDFFont.d.ts
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MSDF (Multi-channel Signed Distance Field) font support.
|
|
3
|
-
*
|
|
4
|
-
* Parses the `msdf-atlas-gen` JSON layout — the de-facto MSDF format produced by
|
|
5
|
-
* Chlumsky's `msdf-atlas-gen` / `msdfgen` — and lays a string out into textured
|
|
6
|
-
* quads positioned in CSS pixels with atlas UVs. Pair {@link MSDFFont.layout}
|
|
7
|
-
* with the WebGL backend's `setMSDFTexture` + `addGlyph` to render GPU text that
|
|
8
|
-
* stays crisp at any scale (and supports outline/glow in the shader).
|
|
9
|
-
*
|
|
10
|
-
* Geometry conventions match the renderer: local space is y-down, top-left
|
|
11
|
-
* origin; UVs use v=0 at the top of the atlas image (atlas uploaded without a
|
|
12
|
-
* Y-flip, the same as `setTexture`/`addSprite`).
|
|
13
|
-
*/
|
|
14
|
-
/** Atlas section of an `msdf-atlas-gen` JSON file. */
|
|
15
|
-
export interface MSDFAtlasInfo {
|
|
16
|
-
/** Field type, e.g. `'msdf'` | `'mtsdf'` | `'sdf'`. */
|
|
17
|
-
type: string;
|
|
18
|
-
/** Distance field range in atlas pixels — drives the shader's edge sharpness. */
|
|
19
|
-
distanceRange: number;
|
|
20
|
-
/** Glyph size the atlas was rasterized at (em → px), informational. */
|
|
21
|
-
size: number;
|
|
22
|
-
/** Atlas image width in pixels. */
|
|
23
|
-
width: number;
|
|
24
|
-
/** Atlas image height in pixels. */
|
|
25
|
-
height: number;
|
|
26
|
-
/** Whether `atlasBounds` are measured from the image bottom or top. */
|
|
27
|
-
yOrigin: 'bottom' | 'top';
|
|
28
|
-
}
|
|
29
|
-
/** Font-wide metrics in em units. */
|
|
30
|
-
export interface MSDFMetrics {
|
|
31
|
-
emSize: number;
|
|
32
|
-
/** Line advance in em (multiply by font size for px). */
|
|
33
|
-
lineHeight: number;
|
|
34
|
-
/** Distance from baseline to the top of the line in em (positive, up). */
|
|
35
|
-
ascender: number;
|
|
36
|
-
/** Distance from baseline to the bottom in em (negative, down). */
|
|
37
|
-
descender: number;
|
|
38
|
-
underlineY?: number;
|
|
39
|
-
underlineThickness?: number;
|
|
40
|
-
}
|
|
41
|
-
/** Em-unit / atlas-pixel rectangle as emitted by `msdf-atlas-gen`. */
|
|
42
|
-
export interface MSDFBounds {
|
|
43
|
-
left: number;
|
|
44
|
-
bottom: number;
|
|
45
|
-
right: number;
|
|
46
|
-
top: number;
|
|
47
|
-
}
|
|
48
|
-
/** One glyph's metrics. Whitespace has `advance` but no plane/atlas bounds. */
|
|
49
|
-
export interface MSDFGlyphDef {
|
|
50
|
-
unicode: number;
|
|
51
|
-
/** Horizontal advance in em units. */
|
|
52
|
-
advance: number;
|
|
53
|
-
/** Quad position relative to the baseline, em units, y-up. */
|
|
54
|
-
planeBounds?: MSDFBounds;
|
|
55
|
-
/** Source rectangle in the atlas, pixels. */
|
|
56
|
-
atlasBounds?: MSDFBounds;
|
|
57
|
-
}
|
|
58
|
-
/** Kerning pair adjustment in em units. */
|
|
59
|
-
export interface MSDFKerning {
|
|
60
|
-
unicode1: number;
|
|
61
|
-
unicode2: number;
|
|
62
|
-
advance: number;
|
|
63
|
-
}
|
|
64
|
-
/** A parsed `msdf-atlas-gen` JSON document. */
|
|
65
|
-
export interface MSDFFontData {
|
|
66
|
-
atlas: MSDFAtlasInfo;
|
|
67
|
-
metrics: MSDFMetrics;
|
|
68
|
-
glyphs: MSDFGlyphDef[];
|
|
69
|
-
kerning?: MSDFKerning[];
|
|
70
|
-
}
|
|
71
|
-
/** A glyph positioned for rendering: a CSS-pixel quad + atlas UVs (0..1). */
|
|
72
|
-
export interface PositionedGlyph {
|
|
73
|
-
/** Source character (may be a surrogate-pair astral codepoint). */
|
|
74
|
-
char: string;
|
|
75
|
-
/** Quad top-left in local CSS pixels (y-down). */
|
|
76
|
-
x: number;
|
|
77
|
-
y: number;
|
|
78
|
-
/** Quad size in CSS pixels. */
|
|
79
|
-
w: number;
|
|
80
|
-
h: number;
|
|
81
|
-
/** Atlas UVs: `(u0,v0)` top-left, `(u1,v1)` bottom-right; v=0 is the atlas top. */
|
|
82
|
-
u0: number;
|
|
83
|
-
v0: number;
|
|
84
|
-
u1: number;
|
|
85
|
-
v1: number;
|
|
86
|
-
}
|
|
87
|
-
/** Result of {@link MSDFFont.layout}. */
|
|
88
|
-
export interface MSDFLayoutResult {
|
|
89
|
-
glyphs: PositionedGlyph[];
|
|
90
|
-
/** Total pen advance of the widest line in CSS pixels. */
|
|
91
|
-
width: number;
|
|
92
|
-
/** `lineCount × lineHeight × fontSize` in CSS pixels. */
|
|
93
|
-
height: number;
|
|
94
|
-
}
|
|
95
|
-
/** Options for {@link MSDFFont.layout}. */
|
|
96
|
-
export interface MSDFLayoutOptions {
|
|
97
|
-
/** Pen origin x (left of the first glyph), CSS pixels. Default 0. */
|
|
98
|
-
x?: number;
|
|
99
|
-
/** Text-block top y (baseline of line 0 = `y + ascender×size`). Default 0. */
|
|
100
|
-
y?: number;
|
|
101
|
-
/** Extra advance added after every glyph, CSS pixels. Default 0. */
|
|
102
|
-
letterSpacing?: number;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* A loaded MSDF font. Construct from parsed {@link MSDFFontData}, or use
|
|
106
|
-
* {@link MSDFFont.parse} to read the JSON string straight from `msdf-atlas-gen`.
|
|
107
|
-
*/
|
|
108
|
-
export declare class MSDFFont {
|
|
109
|
-
private static idCounter;
|
|
110
|
-
readonly id: string;
|
|
111
|
-
readonly data: MSDFFontData;
|
|
112
|
-
private readonly byCode;
|
|
113
|
-
private readonly kern;
|
|
114
|
-
constructor(data: MSDFFontData);
|
|
115
|
-
/** Parse the `msdf-atlas-gen` JSON (string or already-parsed object). */
|
|
116
|
-
static parse(json: string | MSDFFontData): MSDFFont;
|
|
117
|
-
/** Get a glyph's definition by its unicode value in O(1) time. */
|
|
118
|
-
getGlyph(unicode: number): MSDFGlyphDef | undefined;
|
|
119
|
-
/** Distance field range in atlas pixels (for the shader's `u_distanceRange`). */
|
|
120
|
-
get distanceRange(): number;
|
|
121
|
-
get atlasWidth(): number;
|
|
122
|
-
get atlasHeight(): number;
|
|
123
|
-
/**
|
|
124
|
-
* Lay `text` out at `fontSizePx`. Returns positioned quads (skipping glyphs the
|
|
125
|
-
* font doesn't contain), the widest line's advance, and the total block height.
|
|
126
|
-
* Honors `\n`, kerning pairs, and `letterSpacing`.
|
|
127
|
-
*/
|
|
128
|
-
layout(text: string, fontSizePx: number, opts?: MSDFLayoutOptions): MSDFLayoutResult;
|
|
129
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
export interface PreparedContentGridCell {
|
|
2
|
-
/** UTF-16 source start, matching DOM Range offsets. */
|
|
3
|
-
readonly sourceStart: number;
|
|
4
|
-
/** UTF-16 source end, matching DOM Range offsets. */
|
|
5
|
-
readonly sourceEnd: number;
|
|
6
|
-
/** Legal UTF-16 caret offsets relative to `sourceStart`. */
|
|
7
|
-
readonly sourceCaretOffsets: readonly number[];
|
|
8
|
-
/** Contextually shaped glyph text used by the canvas painter. */
|
|
9
|
-
readonly glyph: string;
|
|
10
|
-
/** Visual x coordinate inside the line. */
|
|
11
|
-
readonly x: number;
|
|
12
|
-
/** Grid advance in local CSS pixels. */
|
|
13
|
-
readonly advance: number;
|
|
14
|
-
/** Resolved bidi embedding level. */
|
|
15
|
-
readonly level: number;
|
|
16
|
-
}
|
|
17
|
-
export interface PreparedContentGridLine {
|
|
18
|
-
/** Start of this logical line in {@link PreparedContentGrid.source}. */
|
|
19
|
-
readonly sourceStart: number;
|
|
20
|
-
/** End of visible line content, excluding the hard break. */
|
|
21
|
-
readonly sourceEnd: number;
|
|
22
|
-
/** Start of the next line, thereby owning the intervening hard break. */
|
|
23
|
-
readonly nextSourceStart: number;
|
|
24
|
-
/** Total visual grid width in local CSS pixels. */
|
|
25
|
-
readonly width: number;
|
|
26
|
-
/** Cells stay in logical source order; their x coordinates encode visual order. */
|
|
27
|
-
readonly cells: readonly PreparedContentGridCell[];
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Immutable source-aware geometry shared by canvas grid text and its semantic
|
|
31
|
-
* DOM projection. It deliberately remains independent of syntax highlighting.
|
|
32
|
-
*/
|
|
33
|
-
export interface PreparedContentGrid {
|
|
34
|
-
readonly kind: 'content-grid';
|
|
35
|
-
readonly revision: number;
|
|
36
|
-
readonly source: string;
|
|
37
|
-
readonly font: string;
|
|
38
|
-
readonly cellWidth: number;
|
|
39
|
-
readonly lineHeight: number;
|
|
40
|
-
readonly baseline: number;
|
|
41
|
-
readonly tabSize: number;
|
|
42
|
-
readonly lines: readonly PreparedContentGridLine[];
|
|
43
|
-
}
|
|
44
|
-
export interface PrepareContentGridOptions {
|
|
45
|
-
/** CSS font shorthand shared by canvas and the projected DOM. */
|
|
46
|
-
font: string;
|
|
47
|
-
/** Width of one grid column in local CSS pixels. */
|
|
48
|
-
cellWidth: number;
|
|
49
|
-
/** Visual line advance in local CSS pixels. */
|
|
50
|
-
lineHeight: number;
|
|
51
|
-
/** Canvas baseline relative to each line's top. */
|
|
52
|
-
baseline: number;
|
|
53
|
-
/** Number of columns between tab stops. Defaults to 4. */
|
|
54
|
-
tabSize?: number;
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Compile logical source into one retained grid plan. Canvas paint and native
|
|
58
|
-
* text projection must consume this same object rather than re-segmenting it.
|
|
59
|
-
*/
|
|
60
|
-
export declare function prepareContentGrid(source: string, options: PrepareContentGridOptions): PreparedContentGrid;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Return the baseline offset inside a CSS line box for a canvas-compatible
|
|
3
|
-
* font. Canvas text and a native editor must use this identical value whenever
|
|
4
|
-
* one mirrors the other; CSS otherwise centers font metrics in the line box.
|
|
5
|
-
*
|
|
6
|
-
* The 0.8 fallback preserves the framework's deterministic, DOM-free text
|
|
7
|
-
* contract in SSR and test environments where Canvas 2D is unavailable.
|
|
8
|
-
*/
|
|
9
|
-
export declare function cssLineBoxBaseline(font: string, lineHeight: number): number;
|
|
10
|
-
/** Clear cached browser font metrics after a webfont finishes loading. */
|
|
11
|
-
export declare function clearCssLineBoxMetrics(): void;
|