@glissade/scene 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/layout.d.ts +1 -1
- package/dist/layoutEngine.d.ts +26 -1
- package/dist/layoutEngine.js +53 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as createDisplayListBuilder, A as NodeProps, B as DisplayList, C as WordBox, D as EvalContext, E as BindablePropTarget, F as breakLines, G as FontSpec, H as DrawCommand, I as estimatingMeasurer, J as Rect$1, K as Paint, L as quantize, M as resolveAnchor, N as TextMeasurer, O as HitArea, P as TextMetricsLite, Q as StrokeStyle, R as segmentWords, S as VideoProps, T as AnchorSpec, U as FilterSpec, V as DisplayListBuilder, W as FilterValidationError, X as ResourceId, Y as Resource, Z as ShaderRef, _ as Rect, a as LayoutEngineMissingError, at as applyToPoint, b as TextProps, c as requireLayoutEngine, ct as matEquals, d as Group, et as filtersToCanvasFilter, f as ImageNode, g as PathProps, h as Path, i as LayoutEngine, it as Mat2x3, j as PropInit, k as Node, l as setLayoutEngine, lt as multiply, m as LineBox, n as LayoutChildSpec, nt as validateFilters, ot as fromTRS, p as ImageProps, q as PathSeg, r as LayoutContainerSpec, rt as IDENTITY, s as getLayoutEngine, st as invert, t as LayoutBox, tt as glow, u as Circle, v as ShapeProps, w as roundedRectSegs, x as Video, y as Text, z as BlendMode } from "./layoutEngine.js";
|
|
2
2
|
import { BindableSignal, BoundTimeline, CompiledTimeline, Playhead, Timeline } from "@glissade/core";
|
|
3
3
|
|
|
4
4
|
//#region src/highlight.d.ts
|
|
@@ -218,4 +218,4 @@ declare function bindScene(scene: Scene, doc: Timeline): BindingCacheEntry;
|
|
|
218
218
|
*/
|
|
219
219
|
declare function evaluate(scene: Scene, doc: Timeline, t: number): DisplayList;
|
|
220
220
|
//#endregion
|
|
221
|
-
export { type AnchorSpec, type BindablePropTarget, type BlendMode, type CanvasLike, Circle, ColdAssetError, type Ctx2DLike, type DisplayList, type DisplayListBuilder, type DrawCommand, DuplicateNodeIdError, type EvalContext, type FilterSpec, FilterValidationError, type FontSpec, Group, Highlight, type HighlightProps, type HitArea, IDENTITY, type ImageHandle, ImageNode, type ImageProps, type LayoutBox, type LayoutChildSpec, type LayoutContainerSpec, type LayoutEngine, LayoutEngineMissingError, type LineBox, type Mat2x3, Node, type NodeProps, type Paint, Path, type PathLike, type PathProps, type PathSeg, type PropInit, Raster2D, type Raster2DHost, Rect, type Rect$1 as RectShape, type Resource, type ResourceId, type Scene, type SceneInit, type SceneModule, type ShaderCaps, ShaderEffect, type ShaderEffectProps, type ShaderRef, type ShapeProps, type StrokeStyle, Text, type TextMeasurer, type TextMetricsLite, type TextProps, Video, type VideoFrameSource, type VideoProps, applyToPoint, bindScene, breakLines, createDisplayListBuilder, createScene, estimatingMeasurer, evaluate, filtersToCanvasFilter, fontString, fromTRS, getLayoutEngine, glow, highlight, invert, matEquals, multiply, quantize, requireLayoutEngine, resolveAnchor, roundedRectSegs, setLayoutEngine, validateFilters };
|
|
221
|
+
export { type AnchorSpec, type BindablePropTarget, type BlendMode, type CanvasLike, Circle, ColdAssetError, type Ctx2DLike, type DisplayList, type DisplayListBuilder, type DrawCommand, DuplicateNodeIdError, type EvalContext, type FilterSpec, FilterValidationError, type FontSpec, Group, Highlight, type HighlightProps, type HitArea, IDENTITY, type ImageHandle, ImageNode, type ImageProps, type LayoutBox, type LayoutChildSpec, type LayoutContainerSpec, type LayoutEngine, LayoutEngineMissingError, type LineBox, type Mat2x3, Node, type NodeProps, type Paint, Path, type PathLike, type PathProps, type PathSeg, type PropInit, Raster2D, type Raster2DHost, Rect, type Rect$1 as RectShape, type Resource, type ResourceId, type Scene, type SceneInit, type SceneModule, type ShaderCaps, ShaderEffect, type ShaderEffectProps, type ShaderRef, type ShapeProps, type StrokeStyle, Text, type TextMeasurer, type TextMetricsLite, type TextProps, Video, type VideoFrameSource, type VideoProps, type WordBox, applyToPoint, bindScene, breakLines, createDisplayListBuilder, createScene, estimatingMeasurer, evaluate, filtersToCanvasFilter, fontString, fromTRS, getLayoutEngine, glow, highlight, invert, matEquals, multiply, quantize, requireLayoutEngine, resolveAnchor, roundedRectSegs, segmentWords, setLayoutEngine, validateFilters };
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as validateFilters, D as invert, E as fromTRS, O as matEquals, S as glow, T as applyToPoint, _ as quantize, a as Circle, b as createDisplayListBuilder, c as Path, d as Video, f as roundedRectSegs, g as estimatingMeasurer, h as breakLines, i as setLayoutEngine, k as multiply, l as Rect, m as resolveAnchor, n as getLayoutEngine, o as Group, p as Node, r as requireLayoutEngine, s as ImageNode, t as LayoutEngineMissingError, u as Text, v as segmentWords, w as IDENTITY, x as filtersToCanvasFilter, y as FilterValidationError } from "./layoutEngine.js";
|
|
2
2
|
import { bindTimeline, compileTimeline, createPlayhead, emitDevWarning, evaluateAt, signal } from "@glissade/core";
|
|
3
3
|
//#region src/highlight.ts
|
|
4
4
|
/**
|
|
@@ -563,4 +563,4 @@ function evaluate(scene, doc, t) {
|
|
|
563
563
|
});
|
|
564
564
|
}
|
|
565
565
|
//#endregion
|
|
566
|
-
export { Circle, ColdAssetError, DuplicateNodeIdError, FilterValidationError, Group, Highlight, IDENTITY, ImageNode, LayoutEngineMissingError, Node, Path, Raster2D, Rect, ShaderEffect, Text, Video, applyToPoint, bindScene, breakLines, createDisplayListBuilder, createScene, estimatingMeasurer, evaluate, filtersToCanvasFilter, fontString, fromTRS, getLayoutEngine, glow, highlight, invert, matEquals, multiply, quantize, requireLayoutEngine, resolveAnchor, roundedRectSegs, setLayoutEngine, validateFilters };
|
|
566
|
+
export { Circle, ColdAssetError, DuplicateNodeIdError, FilterValidationError, Group, Highlight, IDENTITY, ImageNode, LayoutEngineMissingError, Node, Path, Raster2D, Rect, ShaderEffect, Text, Video, applyToPoint, bindScene, breakLines, createDisplayListBuilder, createScene, estimatingMeasurer, evaluate, filtersToCanvasFilter, fontString, fromTRS, getLayoutEngine, glow, highlight, invert, matEquals, multiply, quantize, requireLayoutEngine, resolveAnchor, roundedRectSegs, segmentWords, setLayoutEngine, validateFilters };
|
package/dist/layout.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as
|
|
1
|
+
import { A as NodeProps, D as EvalContext, N as TextMeasurer, V as DisplayListBuilder, a as LayoutEngineMissingError, d as Group, i as LayoutEngine, j as PropInit, k as Node, l as setLayoutEngine, n as LayoutChildSpec, o as LayoutResult, r as LayoutContainerSpec, s as getLayoutEngine, t as LayoutBox } from "./layoutEngine.js";
|
|
2
2
|
import { BindableSignal } from "@glissade/core";
|
|
3
3
|
|
|
4
4
|
//#region src/layout.d.ts
|
package/dist/layoutEngine.d.ts
CHANGED
|
@@ -194,6 +194,12 @@ declare function quantize(v: number): number;
|
|
|
194
194
|
* faithful; mount(), the CLI, and exporters always inject the real one.
|
|
195
195
|
*/
|
|
196
196
|
declare const estimatingMeasurer: TextMeasurer;
|
|
197
|
+
/**
|
|
198
|
+
* The draw-path word segmentation (Intl.Segmenter boundaries, punctuation
|
|
199
|
+
* glued to its predecessor) — exported so Text.wordBoxes() boxes EXACTLY the
|
|
200
|
+
* units the breaker flows.
|
|
201
|
+
*/
|
|
202
|
+
declare function segmentWords(text: string): string[];
|
|
197
203
|
/**
|
|
198
204
|
* Greedy line breaking: explicit '\n' always breaks; otherwise word segments
|
|
199
205
|
* flow until maxWidth is exceeded (Intl.Segmenter boundaries, so CJK wraps
|
|
@@ -477,6 +483,16 @@ interface LineBox {
|
|
|
477
483
|
w: number;
|
|
478
484
|
h: number;
|
|
479
485
|
}
|
|
486
|
+
/** One word's ink box within a laid-out line, in the Text node's draw space. */
|
|
487
|
+
interface WordBox {
|
|
488
|
+
text: string;
|
|
489
|
+
/** laid-out line index (blank lines keep their slot in the numbering) */
|
|
490
|
+
line: number;
|
|
491
|
+
x: number;
|
|
492
|
+
y: number;
|
|
493
|
+
w: number;
|
|
494
|
+
h: number;
|
|
495
|
+
}
|
|
480
496
|
interface TextProps extends NodeProps {
|
|
481
497
|
text?: PropInit<string>;
|
|
482
498
|
fill?: PropInit<string>;
|
|
@@ -526,6 +542,15 @@ declare class Text extends Node {
|
|
|
526
542
|
* reveals, selections.
|
|
527
543
|
*/
|
|
528
544
|
lineBoxes(measurer?: TextMeasurer): LineBox[];
|
|
545
|
+
/**
|
|
546
|
+
* Per-word ink boxes within each laid-out line — the SAME segmentation the
|
|
547
|
+
* breaker flows (Intl.Segmenter boundaries, punctuation glued), positioned
|
|
548
|
+
* by cumulative prefix advances so cross-word kerning is exact and word
|
|
549
|
+
* widths sum to the line's width. Whitespace contributes advance but no
|
|
550
|
+
* box. Pair index-wise with a narration manifest's word timestamps for
|
|
551
|
+
* karaoke; draw your own rects for sub-line multi-color token work.
|
|
552
|
+
*/
|
|
553
|
+
wordBoxes(measurer?: TextMeasurer): WordBox[];
|
|
529
554
|
protected draw(out: DisplayListBuilder, ctx: EvalContext): void;
|
|
530
555
|
}
|
|
531
556
|
//#endregion
|
|
@@ -577,4 +602,4 @@ declare function setLayoutEngine(e: LayoutEngine): void;
|
|
|
577
602
|
declare function getLayoutEngine(): LayoutEngine | null;
|
|
578
603
|
declare function requireLayoutEngine(): LayoutEngine;
|
|
579
604
|
//#endregion
|
|
580
|
-
export {
|
|
605
|
+
export { createDisplayListBuilder as $, NodeProps as A, DisplayList as B, WordBox as C, EvalContext as D, BindablePropTarget as E, breakLines as F, FontSpec as G, DrawCommand as H, estimatingMeasurer as I, Rect$1 as J, Paint as K, quantize as L, resolveAnchor as M, TextMeasurer as N, HitArea as O, TextMetricsLite as P, StrokeStyle as Q, segmentWords as R, VideoProps as S, AnchorSpec as T, FilterSpec as U, DisplayListBuilder as V, FilterValidationError as W, ResourceId as X, Resource as Y, ShaderRef as Z, Rect as _, LayoutEngineMissingError as a, applyToPoint as at, TextProps as b, requireLayoutEngine as c, matEquals as ct, Group as d, filtersToCanvasFilter as et, ImageNode as f, PathProps as g, Path as h, LayoutEngine as i, Mat2x3 as it, PropInit as j, Node as k, setLayoutEngine as l, multiply as lt, LineBox as m, LayoutChildSpec as n, validateFilters as nt, LayoutResult as o, fromTRS as ot, ImageProps as p, PathSeg as q, LayoutContainerSpec as r, IDENTITY as rt, getLayoutEngine as s, invert as st, LayoutBox as t, glow as tt, Circle as u, ShapeProps as v, roundedRectSegs as w, Video as x, Text as y, BlendMode as z };
|
package/dist/layoutEngine.js
CHANGED
|
@@ -166,6 +166,11 @@ const estimatingMeasurer = { measureText(text, font) {
|
|
|
166
166
|
};
|
|
167
167
|
} };
|
|
168
168
|
let wordSegmenter;
|
|
169
|
+
/**
|
|
170
|
+
* The draw-path word segmentation (Intl.Segmenter boundaries, punctuation
|
|
171
|
+
* glued to its predecessor) — exported so Text.wordBoxes() boxes EXACTLY the
|
|
172
|
+
* units the breaker flows.
|
|
173
|
+
*/
|
|
169
174
|
function segmentWords(text) {
|
|
170
175
|
if (wordSegmenter === void 0) wordSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter(void 0, { granularity: "word" }) : null;
|
|
171
176
|
if (wordSegmenter) {
|
|
@@ -922,6 +927,53 @@ var Text = class extends Node {
|
|
|
922
927
|
}
|
|
923
928
|
return boxes;
|
|
924
929
|
}
|
|
930
|
+
/**
|
|
931
|
+
* Per-word ink boxes within each laid-out line — the SAME segmentation the
|
|
932
|
+
* breaker flows (Intl.Segmenter boundaries, punctuation glued), positioned
|
|
933
|
+
* by cumulative prefix advances so cross-word kerning is exact and word
|
|
934
|
+
* widths sum to the line's width. Whitespace contributes advance but no
|
|
935
|
+
* box. Pair index-wise with a narration manifest's word timestamps for
|
|
936
|
+
* karaoke; draw your own rects for sub-line multi-color token work.
|
|
937
|
+
*/
|
|
938
|
+
wordBoxes(measurer) {
|
|
939
|
+
const m = measurer ?? this.measurerSource?.() ?? estimatingMeasurer;
|
|
940
|
+
const text = this.text();
|
|
941
|
+
if (!text) return [];
|
|
942
|
+
const font = {
|
|
943
|
+
family: this.fontFamily,
|
|
944
|
+
size: this.fontSize(),
|
|
945
|
+
weight: this.fontWeight
|
|
946
|
+
};
|
|
947
|
+
const maxWidth = this.width();
|
|
948
|
+
const lines = breakLines(text, font, maxWidth > 0 ? maxWidth : void 0, m);
|
|
949
|
+
const step = quantize(font.size * this.lineHeight);
|
|
950
|
+
const boxes = [];
|
|
951
|
+
for (let i = 0; i < lines.length; i++) {
|
|
952
|
+
const line = lines[i];
|
|
953
|
+
if (!line) continue;
|
|
954
|
+
const met = m.measureText(line, font);
|
|
955
|
+
const lineW = quantize(met.width);
|
|
956
|
+
const lineX = this.align === "left" ? 0 : this.align === "center" ? -lineW / 2 : -lineW;
|
|
957
|
+
const y = i * step - met.ascent;
|
|
958
|
+
const h = met.ascent + met.descent;
|
|
959
|
+
let prefix = "";
|
|
960
|
+
for (const seg of segmentWords(line)) {
|
|
961
|
+
const before = prefix === "" ? 0 : m.measureText(prefix, font).width;
|
|
962
|
+
prefix += seg;
|
|
963
|
+
if (seg.trim() === "") continue;
|
|
964
|
+
const after = m.measureText(prefix, font).width;
|
|
965
|
+
boxes.push({
|
|
966
|
+
text: seg,
|
|
967
|
+
line: i,
|
|
968
|
+
x: lineX + before,
|
|
969
|
+
y,
|
|
970
|
+
w: after - before,
|
|
971
|
+
h
|
|
972
|
+
});
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
return boxes;
|
|
976
|
+
}
|
|
925
977
|
draw(out, ctx) {
|
|
926
978
|
const text = this.text();
|
|
927
979
|
if (!text) return;
|
|
@@ -970,4 +1022,4 @@ function requireLayoutEngine() {
|
|
|
970
1022
|
return engine;
|
|
971
1023
|
}
|
|
972
1024
|
//#endregion
|
|
973
|
-
export {
|
|
1025
|
+
export { validateFilters as C, invert as D, fromTRS as E, matEquals as O, glow as S, applyToPoint as T, quantize as _, Circle as a, createDisplayListBuilder as b, Path as c, Video as d, roundedRectSegs as f, estimatingMeasurer as g, breakLines as h, setLayoutEngine as i, multiply as k, Rect as l, resolveAnchor as m, getLayoutEngine as n, Group as o, Node as p, requireLayoutEngine as r, ImageNode as s, LayoutEngineMissingError as t, Text as u, segmentWords as v, IDENTITY as w, filtersToCanvasFilter as x, FilterValidationError as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glissade/scene",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "glissade scene graph: nodes, transforms, DisplayList emission. Renderer-agnostic; zero DOM/Node dependencies.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
],
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"yoga-layout": "^3.2.1",
|
|
23
|
-
"@glissade/core": "0.4.
|
|
23
|
+
"@glissade/core": "0.4.2"
|
|
24
24
|
},
|
|
25
25
|
"repository": {
|
|
26
26
|
"type": "git",
|