@vyaz/core 0.0.14 → 0.1.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/bin/vyaz.js +27 -0
- package/dist/cli/check.d.ts +12 -0
- package/dist/cli/check.d.ts.map +1 -0
- package/dist/cli/check.js +4077 -0
- package/dist/compile/ParagraphCompiler.d.ts +84 -0
- package/dist/compile/ParagraphCompiler.d.ts.map +1 -0
- package/dist/debug/lines-to-yaml.d.ts +14 -0
- package/dist/debug/lines-to-yaml.d.ts.map +1 -0
- package/dist/debug.d.ts +11 -0
- package/dist/debug.d.ts.map +1 -0
- package/dist/debug.js +4 -0
- package/dist/index.browser.d.ts +9 -4
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +3197 -5025
- package/dist/index.d.ts +12 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4714 -788
- package/dist/layout/AutoFitEngine.d.ts.map +1 -1
- package/dist/layout/LineBoxValidator.d.ts +5 -10
- package/dist/layout/LineBoxValidator.d.ts.map +1 -1
- package/dist/layout/ParagraphLayoutEngine.d.ts +13 -8
- package/dist/layout/ParagraphLayoutEngine.d.ts.map +1 -1
- package/dist/layout/PositioningEngine.d.ts +1 -1
- package/dist/layout/PositioningEngine.d.ts.map +1 -1
- package/dist/layout/TextFrameLayoutEngine.d.ts +84 -15
- package/dist/layout/TextFrameLayoutEngine.d.ts.map +1 -1
- package/dist/layout/create-engine.d.ts +32 -0
- package/dist/layout/create-engine.d.ts.map +1 -0
- package/dist/layout/resolve-font.d.ts +25 -0
- package/dist/layout/resolve-font.d.ts.map +1 -0
- package/dist/measure/FontEngine.d.ts +44 -1
- package/dist/measure/FontEngine.d.ts.map +1 -1
- package/dist/measure/FontMetricsProvider.d.ts +3 -10
- package/dist/measure/FontMetricsProvider.d.ts.map +1 -1
- package/dist/measure/FontkitMeasureContext.d.ts +109 -0
- package/dist/measure/FontkitMeasureContext.d.ts.map +1 -0
- package/dist/measure/canvas-polyfill.d.ts +7 -2
- package/dist/measure/canvas-polyfill.d.ts.map +1 -1
- package/dist/types/Document.d.ts +36 -23
- package/dist/types/Document.d.ts.map +1 -1
- package/dist/types/FontTypes.d.ts +1 -1
- package/dist/types/FontTypes.d.ts.map +1 -1
- package/dist/types/LayoutTypes.d.ts +19 -2
- package/dist/types/LayoutTypes.d.ts.map +1 -1
- package/package.json +16 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AutoFitEngine.d.ts","sourceRoot":"","sources":["../../src/layout/AutoFitEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,sBAAsB;AACtB,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAqB;AACrB,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,GACZ,SAAS,
|
|
1
|
+
{"version":3,"file":"AutoFitEngine.d.ts","sourceRoot":"","sources":["../../src/layout/AutoFitEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,sBAAsB;AACtB,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAqB;AACrB,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,SAAS,EACd,KAAK,EAAE,MAAM,GACZ,SAAS,CAgBX;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EACrE,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,EAC/C,OAAO,CAAC,EAAE,cAAc,GACvB,aAAa,CAoCf"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* LineBoxValidator.ts — invariant checks
|
|
2
|
+
* LineBoxValidator.ts — Parley-inspired line-box invariant checks.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* NO_OVERLAP, MONOTONIC_Y, INDEX_CONSIST, WIDTH_FIT, BASELINE_EQ
|
|
4
|
+
* Invariants: NO_OVERLAP, MONOTONIC_Y, INDEX_CONSIST, WIDTH_FIT, BASELINE_EQ.
|
|
6
5
|
*
|
|
7
|
-
* YAML
|
|
6
|
+
* YAML snapshot serialization lives in `../debug/lines-to-yaml.ts` (pulled in
|
|
7
|
+
* only through the `@vyaz/core/debug` entry, so `js-yaml` stays out of the
|
|
8
|
+
* production bundle).
|
|
8
9
|
*/
|
|
9
10
|
import type { Line } from '../types/LayoutTypes.js';
|
|
10
11
|
export interface InvariantError {
|
|
@@ -17,10 +18,4 @@ export interface InvariantError {
|
|
|
17
18
|
* Throws on first violation.
|
|
18
19
|
*/
|
|
19
20
|
export declare function assertLineInvariants(lines: Line[], originalText: string, maxWidth: number): void;
|
|
20
|
-
/**
|
|
21
|
-
* Convert Line[] to YAML string for snapshots.
|
|
22
|
-
* Only semantic data: text, x, width, style.
|
|
23
|
-
* No glyphAdvances, fontMetrics (noise), inlineWidget.
|
|
24
|
-
*/
|
|
25
|
-
export declare function linesToYAML(lines: Line[], paragraphWidth: number, paragraphHeight: number): string;
|
|
26
21
|
//# sourceMappingURL=LineBoxValidator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LineBoxValidator.d.ts","sourceRoot":"","sources":["../../src/layout/LineBoxValidator.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"LineBoxValidator.d.ts","sourceRoot":"","sources":["../../src/layout/LineBoxValidator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAMpD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,GAAG,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,IAAI,EAAE,EACb,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,GACf,IAAI,CAqFN"}
|
|
@@ -3,21 +3,28 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Pipeline:
|
|
5
5
|
* Paragraph
|
|
6
|
-
* → compile (
|
|
6
|
+
* → compile (ParagraphCompiler)
|
|
7
7
|
* → prepareRichInline (pretext)
|
|
8
8
|
* → walkRichInlineLineRanges + materializeRichInlineLineRange (pretext)
|
|
9
9
|
* → positionLines (PositioningEngine)
|
|
10
|
-
*
|
|
10
|
+
*
|
|
11
|
+
* Line-box invariant checks live in `@vyaz/core/debug` (assertLineInvariants);
|
|
12
|
+
* they are not run on the layout hot path.
|
|
11
13
|
*
|
|
12
14
|
* Supports autofit via AutoFitEngine.findScale.
|
|
13
15
|
* Caches PreparedRichInline per paragraph key (Parley LayoutContext pattern).
|
|
14
16
|
*/
|
|
15
|
-
import '../measure/canvas-polyfill.js';
|
|
16
17
|
import type { Paragraph, ListStyle } from '../types/Document.js';
|
|
17
18
|
import type { IFontMetricsProvider } from '../types/FontTypes.js';
|
|
18
19
|
import type { ParagraphLayoutResult } from '../types/LayoutTypes.js';
|
|
20
|
+
import { type OnMissingFont } from './resolve-font.js';
|
|
19
21
|
export declare class ParagraphLayoutEngine {
|
|
22
|
+
/** LRU (Map insertion order) of PreparedRichInline keyed by {@link preparedCacheKey}. */
|
|
20
23
|
private preparedCache;
|
|
24
|
+
private readonly cacheMax;
|
|
25
|
+
constructor(cacheMax?: number);
|
|
26
|
+
/** Drop all cached prepared-line data (e.g. on document close). */
|
|
27
|
+
clearCache(): void;
|
|
21
28
|
/**
|
|
22
29
|
* Layout a single paragraph — basic variant.
|
|
23
30
|
*
|
|
@@ -26,12 +33,10 @@ export declare class ParagraphLayoutEngine {
|
|
|
26
33
|
* @param fontProvider — optional metrics provider (default: fontMetricsProvider)
|
|
27
34
|
* @returns ParagraphLayoutResult with Line[]
|
|
28
35
|
*/
|
|
29
|
-
layout(paragraph: Paragraph, maxWidth: number, yOffset?: number, fontProvider?: IFontMetricsProvider, listStyle?: ListStyle, listIndex?: number, listMarkerWidth?: number): ParagraphLayoutResult;
|
|
36
|
+
layout(paragraph: Paragraph, maxWidth: number, yOffset?: number, fontProvider?: IFontMetricsProvider, listStyle?: ListStyle, listIndex?: number, listMarkerWidth?: number, wantGlyphAdvances?: boolean, mode?: 'browser' | 'office', onMissingFont?: OnMissingFont): ParagraphLayoutResult;
|
|
30
37
|
/**
|
|
31
|
-
* Layout with per-glyph advance widths
|
|
32
|
-
*
|
|
33
|
-
* glyphAdvances are now filled by layout() automatically, so
|
|
34
|
-
* this method is equivalent to layout(). Kept for API compatibility.
|
|
38
|
+
* Layout with per-glyph advance widths filled on every text span
|
|
39
|
+
* (SVG "glyph" preset, caret hit-testing).
|
|
35
40
|
*/
|
|
36
41
|
layoutGlyph(paragraph: Paragraph, maxWidth: number, yOffset?: number): ParagraphLayoutResult;
|
|
37
42
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ParagraphLayoutEngine.d.ts","sourceRoot":"","sources":["../../src/layout/ParagraphLayoutEngine.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"ParagraphLayoutEngine.d.ts","sourceRoot":"","sources":["../../src/layout/ParagraphLayoutEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAQrE,OAAO,EAAqB,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA+E1E,qBAAa,qBAAqB;IAChC,yFAAyF;IACzF,OAAO,CAAC,aAAa,CAAyC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,QAAQ,GAAE,MAAmC;IAIzD,mEAAmE;IACnE,UAAU,IAAI,IAAI;IAIlB;;;;;;;OAOG;IACH,MAAM,CACJ,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAU,EACnB,YAAY,CAAC,EAAE,oBAAoB,EACnC,SAAS,CAAC,EAAE,SAAS,EACrB,SAAS,CAAC,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,EACxB,iBAAiB,GAAE,OAAe,EAClC,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,EAC3B,aAAa,GAAE,aAAuB,GACrC,qBAAqB;IAgLxB;;;OAGG;IACH,WAAW,CACT,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,MAAU,GAClB,qBAAqB;IAIxB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;CAoC7B;AAED,gBAAgB;AAChB,eAAO,MAAM,qBAAqB,EAAE,qBAAmD,CAAC"}
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import type { ParagraphStyle, ListStyle } from '../types/Document.js';
|
|
19
19
|
import type { FontMetrics } from '../types/FontTypes.js';
|
|
20
20
|
import type { Line } from '../types/LayoutTypes.js';
|
|
21
|
-
import type { PreparedRichInlineItem } from '../compile/
|
|
21
|
+
import type { PreparedRichInlineItem } from '../compile/ParagraphCompiler.js';
|
|
22
22
|
interface PretextFragment {
|
|
23
23
|
itemIndex: number;
|
|
24
24
|
text: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PositioningEngine.d.ts","sourceRoot":"","sources":["../../src/layout/PositioningEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAyB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"PositioningEngine.d.ts","sourceRoot":"","sources":["../../src/layout/PositioningEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAgB,MAAM,sBAAsB,CAAC;AACpF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAE,IAAI,EAAyB,MAAM,yBAAyB,CAAC;AAC3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAK9E,UAAU,eAAe;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;IACvD,GAAG,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAED,UAAU,WAAW;IACnB,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACtD;AAmDD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,aAAa,CAC3B,YAAY,EAAE,WAAW,EAAE,EAC3B,KAAK,EAAE,sBAAsB,EAAE,EAC/B,aAAa,EAAE,CAAC,IAAI,EAAE,sBAAsB,KAAK,WAAW,EAC5D,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,YAAI,EAClB,IAAI,EAAE,SAAS,GAAG,QAAQ,YAAY,EACtC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,MAAM,EACrH,GAAG,CAAC,EAAE,MAAM,EACZ,SAAS,CAAC,EAAE,SAAS,EACrB,SAAS,CAAC,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,MAAM,GACvB;IAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CA6gBzC"}
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
* 5. If no frame.height, columns are infinite (all lines stay in column 0)
|
|
22
22
|
*/
|
|
23
23
|
import type { TextFrame } from '../types/Document.js';
|
|
24
|
-
import type { Line } from '../types/LayoutTypes.js';
|
|
24
|
+
import type { Line, LayoutWarning } from '../types/LayoutTypes.js';
|
|
25
|
+
import { ParagraphLayoutEngine } from './ParagraphLayoutEngine.js';
|
|
25
26
|
/**
|
|
26
27
|
* Result of laying out a full TextFrame.
|
|
27
28
|
*
|
|
@@ -31,21 +32,89 @@ import type { Line } from '../types/LayoutTypes.js';
|
|
|
31
32
|
*/
|
|
32
33
|
export interface TextFrameLayoutResult {
|
|
33
34
|
lines: Line[];
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
|
|
35
|
+
/** Intrinsic content box — the text bounding box. */
|
|
36
|
+
content: {
|
|
37
|
+
width: number;
|
|
38
|
+
height: number;
|
|
39
|
+
};
|
|
40
|
+
/** Frame box as given on the input; an axis is omitted when its size was not set. */
|
|
41
|
+
frame: {
|
|
42
|
+
width?: number;
|
|
43
|
+
height?: number;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Whether content spills past the frame on each axis. `false` for an axis
|
|
47
|
+
* with no frame size. Use it to decide auto-grow vs clip vs autofit.
|
|
48
|
+
*/
|
|
49
|
+
overflow: {
|
|
50
|
+
horizontal: boolean;
|
|
51
|
+
vertical: boolean;
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Which size a renderer should use per axis: `'frame'` when a frame size was
|
|
55
|
+
* provided, otherwise `'content'`.
|
|
56
|
+
*/
|
|
57
|
+
fit: {
|
|
58
|
+
horizontal: 'frame' | 'content';
|
|
59
|
+
vertical: 'frame' | 'content';
|
|
60
|
+
};
|
|
61
|
+
/** Present when autofit ran — the scale applied and whether it bottomed out. */
|
|
62
|
+
autofit?: AutofitOutcome;
|
|
63
|
+
/** Non-fatal issues (font fallback / substitution). Omitted when empty. */
|
|
64
|
+
warnings?: LayoutWarning[];
|
|
65
|
+
}
|
|
66
|
+
/** Options for {@link layoutTextFrame}. */
|
|
67
|
+
export interface LayoutOptions {
|
|
68
|
+
/**
|
|
69
|
+
* Fill `Span.glyphAdvances` on every text span. Needed only by the SVG
|
|
70
|
+
* `glyph` preset and by caret hit-testing; off by default because it costs
|
|
71
|
+
* O(chars) font lookups + allocation on every layout.
|
|
72
|
+
*/
|
|
73
|
+
glyphAdvances?: boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Metric mode for this layout, overriding the provider's global mode:
|
|
76
|
+
* - `'browser'` (default) — CSS/Chrome line-box, hhea ascent/descent
|
|
77
|
+
* - `'office'` — PowerPoint/DrawingML line-box, OS/2 winAscent/winDescent
|
|
78
|
+
*/
|
|
79
|
+
mode?: 'browser' | 'office';
|
|
80
|
+
/**
|
|
81
|
+
* Shrink every run's `fontSize` proportionally until the content fits the
|
|
82
|
+
* frame box. `true` uses defaults; an object bounds the minimum size.
|
|
83
|
+
* The chosen scale is reported on `result.autofit`.
|
|
84
|
+
*/
|
|
85
|
+
autofit?: boolean | {
|
|
86
|
+
minFontSize?: number;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* What to do when none of a run's `fontFamily` entries are registered:
|
|
90
|
+
* - `'throw'` (default) — raise `FontNotFoundError`
|
|
91
|
+
* - `'substitute'` — use any registered family and add a `result.warnings`
|
|
92
|
+
* entry instead of failing
|
|
93
|
+
*/
|
|
94
|
+
onMissingFont?: 'throw' | 'substitute';
|
|
95
|
+
/**
|
|
96
|
+
* Measure widths through fontkit's `layout()` — GPOS kerning + GSUB ligatures,
|
|
97
|
+
* i.e. what a browser paints — instead of the default per-code-point advance
|
|
98
|
+
* sum. Applies to line breaking and positioning for this call only. Leave off
|
|
99
|
+
* unless the output is consumed by a browser (SVG `browser` preset).
|
|
100
|
+
*/
|
|
101
|
+
shaping?: boolean;
|
|
102
|
+
}
|
|
103
|
+
/** Autofit outcome, present on the result when {@link LayoutOptions.autofit} was set. */
|
|
104
|
+
export interface AutofitOutcome {
|
|
105
|
+
/** Proportional font-size scale applied (1 = no shrink). */
|
|
106
|
+
scale: number;
|
|
107
|
+
/** True when the min-size floor was hit and content still overflows. */
|
|
108
|
+
clampedToMin: boolean;
|
|
46
109
|
}
|
|
47
110
|
/**
|
|
48
|
-
* Layout a full TextFrame
|
|
111
|
+
* Layout a full TextFrame (paragraphs stacked with Y-offset accumulation).
|
|
112
|
+
*
|
|
113
|
+
* Uses a shared default engine with its own bounded prepared-line cache. For
|
|
114
|
+
* isolation, an explicit cache bound, or `clearCache()`, make your own via
|
|
115
|
+
* {@link createLayoutEngine}.
|
|
49
116
|
*/
|
|
50
|
-
export declare function layoutTextFrame(frame: TextFrame): TextFrameLayoutResult;
|
|
117
|
+
export declare function layoutTextFrame(frame: TextFrame, options?: LayoutOptions): TextFrameLayoutResult;
|
|
118
|
+
/** @internal Shared implementation, parameterised by the engine instance. */
|
|
119
|
+
export declare function runFlow(frame: TextFrame, options: LayoutOptions, engine: ParagraphLayoutEngine): TextFrameLayoutResult;
|
|
51
120
|
//# sourceMappingURL=TextFrameLayoutEngine.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TextFrameLayoutEngine.d.ts","sourceRoot":"","sources":["../../src/layout/TextFrameLayoutEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,SAAS,EAA2C,MAAM,sBAAsB,CAAC;AAC/F,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"TextFrameLayoutEngine.d.ts","sourceRoot":"","sources":["../../src/layout/TextFrameLayoutEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,SAAS,EAA2C,MAAM,sBAAsB,CAAC;AAC/F,OAAO,KAAK,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAyB,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAM1F;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,qDAAqD;IACrD,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,qFAAqF;IACrF,KAAK,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C;;;OAGG;IACH,QAAQ,EAAE;QAAE,UAAU,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,OAAO,CAAA;KAAE,CAAC;IACrD;;;OAGG;IACH,GAAG,EAAE;QAAE,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;QAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE,CAAC;IACxE,gFAAgF;IAChF,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;CAC5B;AAmED,2CAA2C;AAC3C,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC5B;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,GAAG;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C;;;;;OAKG;IACH,aAAa,CAAC,EAAE,OAAO,GAAG,YAAY,CAAC;IACvC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,yFAAyF;AACzF,MAAM,WAAW,cAAc;IAC7B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,GAAE,aAAkB,GAAG,qBAAqB,CAEpG;AAED,6EAA6E;AAC7E,wBAAgB,OAAO,CACrB,KAAK,EAAE,SAAS,EAChB,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,qBAAqB,GAC5B,qBAAqB,CA0SvB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* create-engine.ts — a layout engine you own.
|
|
3
|
+
*
|
|
4
|
+
* `layoutTextFrame` is a convenience wrapper over a shared default engine. When
|
|
5
|
+
* you need isolation (a per-document or per-request cache), an explicit cache
|
|
6
|
+
* bound, or the ability to drop the cache, create your own:
|
|
7
|
+
*
|
|
8
|
+
* ```ts
|
|
9
|
+
* const engine = createLayoutEngine({ cache: { max: 1024 } });
|
|
10
|
+
* const result = engine.layout(frame);
|
|
11
|
+
* engine.clearCache(); // e.g. on document close
|
|
12
|
+
* ```
|
|
13
|
+
*/
|
|
14
|
+
import type { TextFrame } from '../types/Document.js';
|
|
15
|
+
import type { LayoutOptions, TextFrameLayoutResult } from './TextFrameLayoutEngine.js';
|
|
16
|
+
/** Configuration for {@link createLayoutEngine}. */
|
|
17
|
+
export interface LayoutEngineOptions {
|
|
18
|
+
/** Prepared-line cache bound (LRU entries). Default 4096. */
|
|
19
|
+
cache?: {
|
|
20
|
+
max?: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/** A layout engine with its own prepared-line cache. */
|
|
24
|
+
export interface LayoutEngine {
|
|
25
|
+
/** Lay out a full text frame. Same result shape as {@link layoutTextFrame}. */
|
|
26
|
+
layout(frame: TextFrame, options?: LayoutOptions): TextFrameLayoutResult;
|
|
27
|
+
/** Drop all cached prepared-line data. */
|
|
28
|
+
clearCache(): void;
|
|
29
|
+
}
|
|
30
|
+
/** Create a layout engine with an isolated, bounded prepared-line cache. */
|
|
31
|
+
export declare function createLayoutEngine(options?: LayoutEngineOptions): LayoutEngine;
|
|
32
|
+
//# sourceMappingURL=create-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-engine.d.ts","sourceRoot":"","sources":["../../src/layout/create-engine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEvF,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IAClC,6DAA6D;IAC7D,KAAK,CAAC,EAAE;QAAE,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1B;AAED,wDAAwD;AACxD,MAAM,WAAW,YAAY;IAC3B,+EAA+E;IAC/E,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,qBAAqB,CAAC;IACzE,0CAA0C;IAC1C,UAAU,IAAI,IAAI,CAAC;CACpB;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY,CAMlF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* resolve-font.ts — turn a `fontFamily` (single name or CSS-style fallback
|
|
3
|
+
* list) into one concrete registered family, per the `onMissingFont` policy.
|
|
4
|
+
*
|
|
5
|
+
* Everything downstream (positioning, rendering) sees a plain string.
|
|
6
|
+
*/
|
|
7
|
+
import type { FontFace } from '../measure/FontEngine.js';
|
|
8
|
+
import type { LayoutWarning } from '../types/LayoutTypes.js';
|
|
9
|
+
/** How to react when none of a run's requested families are registered. */
|
|
10
|
+
export type OnMissingFont = 'throw' | 'substitute';
|
|
11
|
+
/** Minimal provider surface this module needs. */
|
|
12
|
+
export interface FontResolverLike {
|
|
13
|
+
getFont(family: string, weight?: string, style?: string): FontFace | undefined;
|
|
14
|
+
getRegisteredFamilies(): string[];
|
|
15
|
+
}
|
|
16
|
+
export interface ResolvedFamily {
|
|
17
|
+
family: string;
|
|
18
|
+
warning: Omit<LayoutWarning, 'runIndex'> | null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* @param family run's `fontFamily`: a name, or a fallback list
|
|
22
|
+
* @param onMissing policy when nothing matches (default `'throw'`)
|
|
23
|
+
*/
|
|
24
|
+
export declare function resolveFontFamily(provider: FontResolverLike, family: string | string[], weight: string, style: string, onMissing?: OnMissingFont): ResolvedFamily;
|
|
25
|
+
//# sourceMappingURL=resolve-font.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-font.d.ts","sourceRoot":"","sources":["../../src/layout/resolve-font.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE7D,2EAA2E;AAC3E,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,YAAY,CAAC;AAEnD,kDAAkD;AAClD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC/E,qBAAqB,IAAI,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,IAAI,CAAC,aAAa,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC;CACjD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,gBAAgB,EAC1B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,EACzB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,SAAS,GAAE,aAAuB,GACjC,cAAc,CAqBhB"}
|
|
@@ -11,6 +11,15 @@
|
|
|
11
11
|
* is removed (or when the import is not blocked by stubs).
|
|
12
12
|
*/
|
|
13
13
|
import type { FontMetrics } from '../types/FontTypes.js';
|
|
14
|
+
/**
|
|
15
|
+
* Factor used when a glyph is not present in the font.
|
|
16
|
+
* Multiplied by fontSize to estimate the missing glyph's advance.
|
|
17
|
+
*
|
|
18
|
+
* Lives here, in the fontkit facade, so every measurement path can share one
|
|
19
|
+
* definition without importing FontMetricsProvider (which installs globals as
|
|
20
|
+
* an import side effect).
|
|
21
|
+
*/
|
|
22
|
+
export declare const MISSING_GLYPH_FACTOR = 0.5;
|
|
14
23
|
/** Opaque font face handle returned by FontEngine.create() */
|
|
15
24
|
export interface FontFace {
|
|
16
25
|
/** fontkit font object (private — not meant for direct access) */
|
|
@@ -27,9 +36,43 @@ export interface FontFace {
|
|
|
27
36
|
* Create a font face from a binary buffer.
|
|
28
37
|
*
|
|
29
38
|
* @param buffer Font file bytes (ArrayBuffer in browser, Uint8Array/Buffer in Node.js)
|
|
39
|
+
* @param opts.variation For a variable font, axis values to instance before use
|
|
40
|
+
* (e.g. `{ wght: 700, wdth: 100 }`). Ignored when the font has no axes. Every
|
|
41
|
+
* downstream call — `glyphForCodePoint`, `layout`, metric extraction — then
|
|
42
|
+
* sees the instanced master, matching what a browser renders for that weight.
|
|
30
43
|
* @returns Opaque FontFace handle
|
|
31
44
|
*/
|
|
32
|
-
export declare function createFontFace(buffer: ArrayBuffer | Uint8Array
|
|
45
|
+
export declare function createFontFace(buffer: ArrayBuffer | Uint8Array, opts?: {
|
|
46
|
+
variation?: Record<string, number>;
|
|
47
|
+
}): Promise<FontFace>;
|
|
48
|
+
/** One shaped glyph: its id and its post-GPOS advance / offset, in font units. */
|
|
49
|
+
export interface ShapedGlyph {
|
|
50
|
+
glyphId: number;
|
|
51
|
+
xAdvance: number;
|
|
52
|
+
xOffset: number;
|
|
53
|
+
}
|
|
54
|
+
/** Result of {@link shapeRun}: total advance + per-glyph detail, in font units. */
|
|
55
|
+
export interface ShapedRun {
|
|
56
|
+
/** Sum of every glyph's xAdvance after kerning / ligature substitution. */
|
|
57
|
+
advanceWidth: number;
|
|
58
|
+
glyphs: ShapedGlyph[];
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Shape `text` through fontkit's OpenType layout engine — the same GPOS kerning
|
|
62
|
+
* and GSUB substitutions (`liga`, `clig`, `calt`, `ccmp`) a browser applies by
|
|
63
|
+
* default. Use this instead of summing {@link getGlyphAdvance} when the measured
|
|
64
|
+
* width has to line up with what the browser will actually paint.
|
|
65
|
+
*
|
|
66
|
+
* Widths are in font units; multiply by `fontSize / unitsPerEm`.
|
|
67
|
+
*
|
|
68
|
+
* @param opts.features OpenType feature overrides, e.g. `{ liga: false }` to
|
|
69
|
+
* emulate `text-rendering: optimizeSpeed`. Omit for browser-default behaviour.
|
|
70
|
+
*/
|
|
71
|
+
export declare function shapeRun(font: FontFace, text: string, opts?: {
|
|
72
|
+
features?: Record<string, boolean>;
|
|
73
|
+
script?: string;
|
|
74
|
+
language?: string;
|
|
75
|
+
}): ShapedRun;
|
|
33
76
|
/**
|
|
34
77
|
* Get the advance width (in font units) for a single code point.
|
|
35
78
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontEngine.d.ts","sourceRoot":"","sources":["../../src/measure/FontEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"FontEngine.d.ts","sourceRoot":"","sources":["../../src/measure/FontEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAIzD;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,MAAM,CAAC;AAKxC,8DAA8D;AAC9D,MAAM,WAAW,QAAQ;IACvB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;IACnB,kDAAkD;IAClD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CACpC;AAkDD;;;;;;;;;GASG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,WAAW,GAAG,UAAU,EAChC,IAAI,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC5C,OAAO,CAAC,QAAQ,CAAC,CAWnB;AAID,kFAAkF;AAClF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,mFAAmF;AACnF,MAAM,WAAW,SAAS;IACxB,2EAA2E;IAC3E,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,QAAQ,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAChF,SAAS,CAYX;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIhF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,WAAW,CAqB7G;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,OAAO,CAAC,CAO9D"}
|
|
@@ -14,11 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import type { FontMetrics, IFontMetricsProvider } from '../types/FontTypes.js';
|
|
16
16
|
import type { FontFace } from './FontEngine.js';
|
|
17
|
-
|
|
18
|
-
* Factor used when a glyph is not found in the font.
|
|
19
|
-
* Multiplied by fontSize to estimate the missing glyph width.
|
|
20
|
-
*/
|
|
21
|
-
export declare const MISSING_GLYPH_FACTOR = 0.5;
|
|
17
|
+
export { MISSING_GLYPH_FACTOR } from './FontEngine.js';
|
|
22
18
|
/**
|
|
23
19
|
* Font metrics provider — registers, resolves, and measures fonts.
|
|
24
20
|
*
|
|
@@ -58,10 +54,6 @@ export declare class FontMetricsProvider implements IFontMetricsProvider {
|
|
|
58
54
|
setMode(mode: 'browser' | 'office'): void;
|
|
59
55
|
/** Get current measurement mode. */
|
|
60
56
|
getMode(): 'browser' | 'office';
|
|
61
|
-
/**
|
|
62
|
-
* @internal Flatten the nested registry for office mode.
|
|
63
|
-
*/
|
|
64
|
-
private _flattenCache;
|
|
65
57
|
/**
|
|
66
58
|
* Register a binary font for use with fontkit.
|
|
67
59
|
*
|
|
@@ -75,6 +67,7 @@ export declare class FontMetricsProvider implements IFontMetricsProvider {
|
|
|
75
67
|
registerFont(family: string, options: {
|
|
76
68
|
weight?: string;
|
|
77
69
|
style?: string;
|
|
70
|
+
variation?: Record<string, number>;
|
|
78
71
|
}, source: string | ArrayBuffer | Uint8Array, sourcePath?: string): Promise<void>;
|
|
79
72
|
/** @internal Internal registration logic */
|
|
80
73
|
private _registerFontInternal;
|
|
@@ -117,7 +110,7 @@ export declare class FontMetricsProvider implements IFontMetricsProvider {
|
|
|
117
110
|
*
|
|
118
111
|
* @throws FontNotFoundError when font is neither registered nor available via Canvas
|
|
119
112
|
*/
|
|
120
|
-
getMetrics(fontFamily: string, fontSize: number, weight?: string, style?: string): FontMetrics;
|
|
113
|
+
getMetrics(fontFamily: string, fontSize: number, weight?: string, style?: string, mode?: 'browser' | 'office'): FontMetrics;
|
|
121
114
|
}
|
|
122
115
|
/** Singleton */
|
|
123
116
|
export declare const fontMetricsProvider: FontMetricsProvider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FontMetricsProvider.d.ts","sourceRoot":"","sources":["../../src/measure/FontMetricsProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"FontMetricsProvider.d.ts","sourceRoot":"","sources":["../../src/measure/FontMetricsProvider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC/E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAQhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAyEvD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,mBAAoB,YAAW,oBAAoB;IAC9D,gEAAgE;IAChE,OAAO,CAAC,QAAQ,CAA4C;IAE5D,gEAAgE;IAChE,OAAO,CAAC,YAAY,CAAkC;IAEtD,gBAAgB;IAChB,OAAO,CAAC,IAAI,CAAmC;IAE/C,qFAAqF;IACrF,OAAO,CAAC,oBAAoB,CAA4B;IAExD,2EAA2E;IAC3E,OAAO,CAAC,cAAc,CAAoD;IAC1E,gBAAgB;IAChB,OAAO,CAAC,WAAW,CAA6E;IAEhG,wDAAwD;IACxD,OAAO,CAAC,kBAAkB;IAe1B;;;;OAIG;IACH,OAAO,CAAC,IAAI,EAAE,SAAS,GAAG,QAAQ,GAAG,IAAI;IASzC,oCAAoC;IACpC,OAAO,IAAI,SAAS,GAAG,QAAQ;IAM/B;;;;;;;;;OASG;IACG,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,EAChF,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,UAAU,EACzC,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAUhB,4CAA4C;YAC9B,qBAAqB;IAmCnC;;;;;OAKG;IACG,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC;IAMlD;;;;OAIG;IACH,qBAAqB,IAAI,MAAM,EAAE;IAIjC;;;;;OAKG;IACH,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAO3C;;;OAGG;IACH,OAAO,CACL,MAAM,EAAE,MAAM,EACd,MAAM,SAAW,EACjB,KAAK,SAAW,GACf,QAAQ,GAAG,SAAS;IAMvB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAsEpB;;;;;;;;OAQG;IACH,UAAU,CACR,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,MAAM,SAAW,EACjB,KAAK,SAAW,EAChB,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,GAC1B,WAAW;CAgFf;AAED,gBAAgB;AAChB,eAAO,MAAM,mBAAmB,EAAE,mBAA+C,CAAC"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FontkitMeasureContext.ts — the measurement seam for vendored pretext.
|
|
3
|
+
*
|
|
4
|
+
* `src/vendor/pretext/measurement.js` calls `getMeasureContext()` from this
|
|
5
|
+
* module instead of reaching for a canvas 2d context. That is the whole
|
|
6
|
+
* integration: pretext only ever uses two members of the object it gets back —
|
|
7
|
+
* `ctx.font = "..."` and `ctx.measureText(s).width` — so the contract is tiny.
|
|
8
|
+
* It draws nothing, and it reads no other property (letter-spacing is pretext's
|
|
9
|
+
* own arithmetic, not the canvas attribute).
|
|
10
|
+
*
|
|
11
|
+
* Backends:
|
|
12
|
+
*
|
|
13
|
+
* - fontkit (the default; installed by `ParagraphLayoutEngine` at module load
|
|
14
|
+
* via `setMeasureContext(createFontkitMeasureContext(...))`) — measures from
|
|
15
|
+
* the font tables. Same per-code-point advances and missing-glyph policy as
|
|
16
|
+
* glyph positioning, so line breaking and positioning agree.
|
|
17
|
+
* - canvas (`createCanvasMeasureContext`) — pretext's original behaviour, kept
|
|
18
|
+
* only as a browser-only escape hatch via `setMeasureContext(null)`. It
|
|
19
|
+
* needs a real `OffscreenCanvas`/`document`; in Node/Bun it now throws
|
|
20
|
+
* rather than pulling a canvas polyfill.
|
|
21
|
+
*
|
|
22
|
+
* Shaping (kerning, ligatures via `font.layout()`) is a separate, later change.
|
|
23
|
+
* Landing it at the same time would make the snapshot delta unreadable.
|
|
24
|
+
*/
|
|
25
|
+
import type { FontFace } from './FontEngine.js';
|
|
26
|
+
/**
|
|
27
|
+
* The slice of `CanvasRenderingContext2D` that pretext actually consumes.
|
|
28
|
+
*/
|
|
29
|
+
export interface MeasureContextLike {
|
|
30
|
+
font: string;
|
|
31
|
+
measureText(text: string): {
|
|
32
|
+
width: number;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Font lookup, structurally satisfied by `FontMetricsProvider`.
|
|
37
|
+
* Kept minimal so this module does not depend on the provider.
|
|
38
|
+
*/
|
|
39
|
+
export interface FontResolver {
|
|
40
|
+
getFont(family: string, weight?: string, style?: string): FontFace | undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* How widths are computed from the font tables.
|
|
44
|
+
*
|
|
45
|
+
* - `'advance'` (default) — Σ per-code-point `advanceWidth`. Fast, and
|
|
46
|
+
* shaping-invariant, but ignores kerning and ligatures, so it drifts from
|
|
47
|
+
* what a browser paints (up to a few px per word on a kerned Latin font).
|
|
48
|
+
* - `'shape'` — fontkit `layout()` advance: GPOS kerning + GSUB (`liga`,
|
|
49
|
+
* `clig`, `calt`, `ccmp`), i.e. browser-default behaviour. Use for the SVG
|
|
50
|
+
* `browser` preset when on-screen width has to match the layout.
|
|
51
|
+
*/
|
|
52
|
+
export interface MeasureProfile {
|
|
53
|
+
engine: 'advance' | 'shape';
|
|
54
|
+
/** `'shape'` only — OpenType feature overrides, e.g. `{ liga: false }`. */
|
|
55
|
+
features?: Record<string, boolean>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Register a callback fired whenever {@link setMeasureProfile} changes the
|
|
59
|
+
* profile — used to drop pretext's per-segment width cache, which is keyed by
|
|
60
|
+
* text only and would otherwise serve `advance` widths to a `shape` layout.
|
|
61
|
+
*/
|
|
62
|
+
export declare function setProfileChangeHook(fn: (() => void) | null): void;
|
|
63
|
+
/** Install the measurement profile used by every fontkit-backed measure path. */
|
|
64
|
+
export declare function setMeasureProfile(next: MeasureProfile): void;
|
|
65
|
+
/** The active measurement profile. */
|
|
66
|
+
export declare function getMeasureProfile(): MeasureProfile;
|
|
67
|
+
/**
|
|
68
|
+
* Install the measure context pretext will use.
|
|
69
|
+
*
|
|
70
|
+
* Pass `null` to fall back to canvas. Takes effect on the next measurement —
|
|
71
|
+
* unlike upstream, nothing is latched, so this is safe to flip in tests.
|
|
72
|
+
*/
|
|
73
|
+
export declare function setMeasureContext(ctx: MeasureContextLike | null): void;
|
|
74
|
+
/** The currently installed context, or `null` when on the canvas fallback. */
|
|
75
|
+
export declare function getInstalledMeasureContext(): MeasureContextLike | null;
|
|
76
|
+
/**
|
|
77
|
+
* Called by vendored pretext on every measurement.
|
|
78
|
+
*
|
|
79
|
+
* Resolution is lazy and per-call rather than latched at module init, so there
|
|
80
|
+
* is no installation order to get wrong and no window in which a worker thread
|
|
81
|
+
* measures through the wrong backend.
|
|
82
|
+
*/
|
|
83
|
+
export declare function getMeasureContext(): MeasureContextLike;
|
|
84
|
+
/**
|
|
85
|
+
* Reproduces pretext's original `getMeasureContext()`. Browser-only: needs a
|
|
86
|
+
* real `OffscreenCanvas` or `document`. Only reached after an explicit
|
|
87
|
+
* `setMeasureContext(null)`; the fontkit backend is the default everywhere.
|
|
88
|
+
*/
|
|
89
|
+
export declare function createCanvasMeasureContext(): MeasureContextLike;
|
|
90
|
+
/**
|
|
91
|
+
* Build a measure context backed by the font tables.
|
|
92
|
+
*
|
|
93
|
+
* @param resolver - font lookup, normally the shared `fontMetricsProvider`
|
|
94
|
+
*/
|
|
95
|
+
/**
|
|
96
|
+
* Pixel width of `text` under `profile`. Shared by the pretext measure context
|
|
97
|
+
* and `ParagraphLayoutEngine`'s fragment measurement so line breaking and
|
|
98
|
+
* positioning never disagree.
|
|
99
|
+
*
|
|
100
|
+
* - `advance` — Σ per-code-point `advanceWidth`, surrogate-aware, with the
|
|
101
|
+
* `MISSING_GLYPH_FACTOR · fontSize` estimate for absent glyphs.
|
|
102
|
+
* - `shape` — fontkit `layout()` advance (kerning + ligatures). Missing
|
|
103
|
+
* glyphs there fall back to the same per-code-point estimate for the
|
|
104
|
+
* stretch that produced no advance, so the two profiles agree on
|
|
105
|
+
* un-shapeable text.
|
|
106
|
+
*/
|
|
107
|
+
export declare function measurePx(raw: any, scale: number, fontSize: number, text: string, prof?: MeasureProfile): number;
|
|
108
|
+
export declare function createFontkitMeasureContext(resolver: FontResolver): MeasureContextLike;
|
|
109
|
+
//# sourceMappingURL=FontkitMeasureContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FontkitMeasureContext.d.ts","sourceRoot":"","sources":["../../src/measure/FontkitMeasureContext.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAMhD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,CAAC;CAChF;AAID;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC;IAC5B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAKD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,GAAG,IAAI,CAElE;AAED,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAI5D;AAED,sCAAsC;AACtC,wBAAgB,iBAAiB,IAAI,cAAc,CAElD;AAOD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,kBAAkB,GAAG,IAAI,GAAG,IAAI,CAEtE;AAED,8EAA8E;AAC9E,wBAAgB,0BAA0B,IAAI,kBAAkB,GAAG,IAAI,CAEtE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,IAAI,kBAAkB,CAItD;AAID;;;;GAIG;AACH,wBAAgB,0BAA0B,IAAI,kBAAkB,CAW/D;AAqDD;;;;GAIG;AACH;;;;;;;;;;;GAWG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,cAAwB,GAC7B,MAAM,CA8BR;AAED,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,YAAY,GAAG,kBAAkB,CA+CtF"}
|
|
@@ -11,8 +11,13 @@
|
|
|
11
11
|
* Exports enableOfficeTextMeasure / disableOfficeTextMeasure —
|
|
12
12
|
* ctx.measureText override for FontEngine-based measurements in Office mode.
|
|
13
13
|
*
|
|
14
|
-
* ⚠️
|
|
15
|
-
*
|
|
14
|
+
* ⚠️ Node.js built-in module access is synchronous via process.getBuiltinModule
|
|
15
|
+
* (Node ≥20.16 / ≥22, Bun ≥1.1) to avoid top-level await race conditions
|
|
16
|
+
* in worker threads (e.g. Piscina). The previous implementation used
|
|
17
|
+
* `await import('module')` which created a race window where layoutTextFrame
|
|
18
|
+
* could be called before the polyfill initialised, returning 0×0.
|
|
19
|
+
*
|
|
20
|
+
* @see https://nodejs.org/api/process.html#processgetbuiltinmoduleid
|
|
16
21
|
*/
|
|
17
22
|
/**
|
|
18
23
|
* Register a font with @napi-rs/canvas so ctx.measureText() works in Node.js.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canvas-polyfill.d.ts","sourceRoot":"","sources":["../../src/measure/canvas-polyfill.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"canvas-polyfill.d.ts","sourceRoot":"","sources":["../../src/measure/canvas-polyfill.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAwNH;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAUzE;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI,CASzE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,IAAI,CAS/C"}
|