modern-text 1.11.1 → 2.0.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/README.md +283 -22
- package/dist/deformations/index.cjs +566 -0
- package/dist/deformations/index.d.cts +11 -0
- package/dist/deformations/index.d.mts +11 -0
- package/dist/deformations/index.d.ts +11 -0
- package/dist/deformations/index.mjs +563 -0
- package/dist/index.cjs +15 -3
- package/dist/index.d.cts +186 -6
- package/dist/index.d.mts +186 -6
- package/dist/index.d.ts +186 -6
- package/dist/index.js +6 -5
- package/dist/index.mjs +4 -2
- package/dist/shared/modern-text.B2xfrqDc.cjs +556 -0
- package/dist/shared/modern-text.BD7PBYt7.d.cts +100 -0
- package/dist/shared/modern-text.BxijkspX.d.ts +100 -0
- package/dist/shared/{modern-text.BKZQdmgG.cjs → modern-text.CBgc-cQ1.cjs} +288 -18
- package/dist/shared/modern-text.CYa4lfoG.d.mts +100 -0
- package/dist/shared/{modern-text.Dqw5Z6MV.mjs → modern-text.ChzjFjsk.mjs} +283 -13
- package/dist/shared/{modern-text.Db7Uoht6.d.cts → modern-text.D4WopQCu.d.cts} +56 -22
- package/dist/shared/{modern-text.Db7Uoht6.d.mts → modern-text.D4WopQCu.d.mts} +56 -22
- package/dist/shared/{modern-text.Db7Uoht6.d.ts → modern-text.D4WopQCu.d.ts} +56 -22
- package/dist/shared/modern-text.JF1ny7A-.mjs +550 -0
- package/dist/shared/modern-text.MC5bIC9E.cjs +316 -0
- package/dist/shared/modern-text.fT17R5HY.mjs +310 -0
- package/dist/web-components/index.cjs +2 -1
- package/dist/web-components/index.d.cts +1 -1
- package/dist/web-components/index.d.mts +1 -1
- package/dist/web-components/index.d.ts +1 -1
- package/dist/web-components/index.mjs +2 -1
- package/package.json +12 -7
package/dist/index.d.cts
CHANGED
|
@@ -1,11 +1,72 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { C as Canvas2DRenderer,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import 'modern-
|
|
1
|
+
import { i as Plugin, k as TextMeasurer, P as Paragraph, M as MeasureDomResult, a as Character, O as Options, c as MeasureResult, R as RenderOptions, T as Text } from './shared/modern-text.D4WopQCu.cjs';
|
|
2
|
+
export { C as Canvas2DRenderer, D as DomMeasurer, b as DrawShapePathsOptions, F as Fragment, d as MeasuredCharacter, e as MeasuredCharacterRect, f as MeasuredFragment, g as MeasuredParagraph, h as MeasurerKind, j as TextEvents, t as textDefaultStyle } from './shared/modern-text.D4WopQCu.cjs';
|
|
3
|
+
import { Fonts } from 'modern-font';
|
|
4
|
+
import { FullStyle, NormalizedStyle, NormalizedHighlight, NormalizedEffect } from 'modern-idoc';
|
|
5
|
+
import { BoundingBox, Vector2, Path2DSet, Transform2D } from 'modern-path2d';
|
|
6
|
+
import { c as DeformationPreset } from './shared/modern-text.BD7PBYt7.cjs';
|
|
7
|
+
export { B as BendContext, a as BendPreset, C as CurvePreset, D as DeformationCharInfo, b as DeformationCurve, F as FfdContext, d as FfdPreset, O as OffsetPreset, V as VerbatimContext } from './shared/modern-text.BD7PBYt7.cjs';
|
|
6
8
|
|
|
7
9
|
declare function definePlugin(options: Plugin): Plugin;
|
|
8
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Pure-JS, DOM-free text measurer — a drop-in alternative to {@link DomMeasurer}.
|
|
13
|
+
*
|
|
14
|
+
* Instead of mounting a `<section>/<ul>/<li>/<span>` tree and reading
|
|
15
|
+
* `getBoundingClientRect()`, it computes the same four-level boxes
|
|
16
|
+
* (`character.inlineBox`/`lineBox`, `fragment.inlineBox`, `paragraph.lineBox`)
|
|
17
|
+
* from `modern-font` glyph advances, so the downstream
|
|
18
|
+
* measure → glyph → plugin pipeline is unchanged and it runs in Node/SSR/Worker.
|
|
19
|
+
*
|
|
20
|
+
* ## Scope
|
|
21
|
+
* - `horizontal-tb` (LTR) and `vertical-rl` (columns right-to-left, glyphs top↓)
|
|
22
|
+
* - line breaking: `word-break: break-all` (greedy, break anywhere) + explicit `\n`
|
|
23
|
+
* - per-line `text-align` (start/left/center/end/right), `text-indent` (first line)
|
|
24
|
+
* - box model: root + paragraph `padding`/`margin` (horizontal), `letter-spacing`,
|
|
25
|
+
* `line-height`; block `vertical-align` (top/middle/bottom) at fixed height
|
|
26
|
+
*
|
|
27
|
+
* ## Not yet implemented (TODO)
|
|
28
|
+
* - UAX#14 `word-break: normal` + 避头尾/kinsoku (`line-break`)
|
|
29
|
+
* - BiDi, per-fragment inline `vertical-align`, borders
|
|
30
|
+
* - vertical: per-paragraph margin/padding and block alignment
|
|
31
|
+
* - kerning/ligatures (GSUB/GPOS) — fine for CJK, diverges for proportional Latin
|
|
32
|
+
*
|
|
33
|
+
* Coordinates are relative to the root border-box top-left (matching the DOM
|
|
34
|
+
* measurer, whose rects are taken relative to `section.getBoundingClientRect()`).
|
|
35
|
+
*/
|
|
36
|
+
declare class FontMeasurer implements TextMeasurer {
|
|
37
|
+
measure(paragraphs: Paragraph[], rootStyle: FullStyle, _dom?: HTMLElement, fonts?: Fonts): MeasureDomResult;
|
|
38
|
+
protected _rootPadding(rootStyle: FullStyle): {
|
|
39
|
+
top: number;
|
|
40
|
+
right: number;
|
|
41
|
+
bottom: number;
|
|
42
|
+
left: number;
|
|
43
|
+
};
|
|
44
|
+
protected _measureHorizontal(paragraphs: Paragraph[], rootStyle: FullStyle): MeasureDomResult;
|
|
45
|
+
/**
|
|
46
|
+
* Vertical writing-mode (`vertical-rl`): columns stack right-to-left, glyphs
|
|
47
|
+
* flow top→bottom. It is the horizontal layout with the inline and block axes
|
|
48
|
+
* swapped — the inline (down-column) advance is `advanceWidth` (CJK upright = em;
|
|
49
|
+
* Latin is rotated, so its advance ≈ its width), the cross-axis content box is
|
|
50
|
+
* `advanceHeight`, and the column thickness is `fontHeight`. The lineBox is
|
|
51
|
+
* derived exactly as DomMeasurer.measureParagraphDom's vertical branch, so it
|
|
52
|
+
* stays accurate even though inlineBox carries the content-box rounding residual.
|
|
53
|
+
*
|
|
54
|
+
* v1: `vertical-rl` only; no per-paragraph margin/padding or block alignment.
|
|
55
|
+
*/
|
|
56
|
+
protected _measureVertical(paragraphs: Paragraph[], rootStyle: FullStyle): MeasureDomResult;
|
|
57
|
+
/** Advance step including CSS letter-spacing (px). */
|
|
58
|
+
protected _advance(character: Character): number;
|
|
59
|
+
/**
|
|
60
|
+
* Break a paragraph's characters into visual lines.
|
|
61
|
+
* v1: `word-break: break-all` (break before any character that would overflow)
|
|
62
|
+
* plus explicit `\n`/`\r` hard breaks. The newline itself occupies no line box.
|
|
63
|
+
*/
|
|
64
|
+
protected _breakLines(paragraph: Paragraph, avail: number): Character[][];
|
|
65
|
+
protected _unionInto(target: BoundingBox, boxes: BoundingBox[]): void;
|
|
66
|
+
protected _shiftAll(paragraphs: Paragraph[], dy: number): void;
|
|
67
|
+
dispose(): void;
|
|
68
|
+
}
|
|
69
|
+
|
|
9
70
|
declare function measureText(options: Options, load: true): Promise<MeasureResult>;
|
|
10
71
|
declare function measureText(options: Options): MeasureResult;
|
|
11
72
|
|
|
@@ -15,6 +76,125 @@ declare function renderText(options: RenderTextOptions): void;
|
|
|
15
76
|
|
|
16
77
|
declare function backgroundPlugin(): Plugin;
|
|
17
78
|
|
|
79
|
+
/**
|
|
80
|
+
* 这些曲线类用于「逐字(-by-word)」沿形状排布文字。
|
|
81
|
+
*
|
|
82
|
+
* 旧版变形代码针对 `modern-path2d@0.2.5` 编写,该版本内置了
|
|
83
|
+
* `CircleCurve` / `EllipseCurve` / `HeartCurve` / `PolygonCurve` / `RectangularCurve`,
|
|
84
|
+
* 当前版本(1.6.x)已不再导出。这里从 0.2.5 原样移植其实现,
|
|
85
|
+
* 仅做 Vector2 API 适配(`copy`→`copyFrom`、`new Vector2().lerpVectors`→`Vector2.lerp`),
|
|
86
|
+
* 以保证逐字排布效果与原版一致。
|
|
87
|
+
*
|
|
88
|
+
* 仅保留 deformer 实际用到的方法:getPoint / getPointAt / getTangent / getNormal。
|
|
89
|
+
*/
|
|
90
|
+
declare abstract class ShapeCurve {
|
|
91
|
+
arcLengthDivisions: number;
|
|
92
|
+
protected _cacheArcLengths?: number[];
|
|
93
|
+
protected _needsUpdate: boolean;
|
|
94
|
+
abstract getPoint(t: number, output?: Vector2): Vector2;
|
|
95
|
+
getPointAt(u: number, output?: Vector2): Vector2;
|
|
96
|
+
getLength(): number;
|
|
97
|
+
getLengths(divisions?: number): number[];
|
|
98
|
+
getUToTMapping(u: number, distance?: number): number;
|
|
99
|
+
getTangent(t: number, output?: Vector2): Vector2;
|
|
100
|
+
getNormal(t: number, output?: Vector2): Vector2;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 分段曲线基类:由若干子曲线拼成,`getCurve(t)` 选中子曲线并把 `curveT` 设为其局部参数,
|
|
104
|
+
* 其余取点/切线/法线统一委托给选中的子曲线。
|
|
105
|
+
*/
|
|
106
|
+
declare abstract class SegmentedCurve extends ShapeCurve {
|
|
107
|
+
protected curveT: number;
|
|
108
|
+
abstract getCurve(t: number): ShapeCurve;
|
|
109
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
110
|
+
getPointAt(u: number, output?: Vector2): Vector2;
|
|
111
|
+
getTangent(t: number, output?: Vector2): Vector2;
|
|
112
|
+
getNormal(t: number, output?: Vector2): Vector2;
|
|
113
|
+
}
|
|
114
|
+
declare class LineShapeCurve extends ShapeCurve {
|
|
115
|
+
start: Vector2;
|
|
116
|
+
end: Vector2;
|
|
117
|
+
constructor(start: Vector2, end: Vector2);
|
|
118
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
119
|
+
getPointAt(u: number, output?: Vector2): Vector2;
|
|
120
|
+
getTangent(_t: number, output?: Vector2): Vector2;
|
|
121
|
+
}
|
|
122
|
+
declare class CircleCurve extends ShapeCurve {
|
|
123
|
+
center: Vector2;
|
|
124
|
+
radius: number;
|
|
125
|
+
start: number;
|
|
126
|
+
end: number;
|
|
127
|
+
constructor(center: Vector2, radius: number, start?: number, end?: number);
|
|
128
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
129
|
+
getTangent(t: number, output?: Vector2): Vector2;
|
|
130
|
+
getNormal(t: number, output?: Vector2): Vector2;
|
|
131
|
+
}
|
|
132
|
+
declare class EllipseCurve extends ShapeCurve {
|
|
133
|
+
center: Vector2;
|
|
134
|
+
radiusX: number;
|
|
135
|
+
radiusY: number;
|
|
136
|
+
rotation: number;
|
|
137
|
+
startAngle: number;
|
|
138
|
+
endAngle: number;
|
|
139
|
+
clockwise: boolean;
|
|
140
|
+
constructor(center?: Vector2, radiusX?: number, radiusY?: number, rotation?: number, startAngle?: number, endAngle?: number, clockwise?: boolean);
|
|
141
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
142
|
+
}
|
|
143
|
+
declare class HeartCurve extends SegmentedCurve {
|
|
144
|
+
center: Vector2;
|
|
145
|
+
size: number;
|
|
146
|
+
start: number;
|
|
147
|
+
end: number;
|
|
148
|
+
protected curves: ShapeCurve[];
|
|
149
|
+
constructor(center: Vector2, size: number, start?: number, end?: number);
|
|
150
|
+
update(): this;
|
|
151
|
+
getCurve(t: number): ShapeCurve;
|
|
152
|
+
}
|
|
153
|
+
declare class PolygonCurve extends SegmentedCurve {
|
|
154
|
+
center: Vector2;
|
|
155
|
+
radius: number;
|
|
156
|
+
number: number;
|
|
157
|
+
start: number;
|
|
158
|
+
end: number;
|
|
159
|
+
protected curves: LineShapeCurve[];
|
|
160
|
+
protected points: Vector2[];
|
|
161
|
+
constructor(center: Vector2, radius?: number, number?: number, start?: number, end?: number);
|
|
162
|
+
update(): this;
|
|
163
|
+
getCurve(t: number): LineShapeCurve;
|
|
164
|
+
}
|
|
165
|
+
declare class RectangularCurve extends SegmentedCurve {
|
|
166
|
+
center: Vector2;
|
|
167
|
+
rx: number;
|
|
168
|
+
aspectRatio: number;
|
|
169
|
+
start: number;
|
|
170
|
+
end: number;
|
|
171
|
+
protected curves: LineShapeCurve[];
|
|
172
|
+
constructor(center: Vector2, rx: number, aspectRatio?: number, start?: number, end?: number);
|
|
173
|
+
update(): this;
|
|
174
|
+
getCurve(t: number): LineShapeCurve;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* 注册一个变形预设(库外部定义,运行时透传)。
|
|
179
|
+
* 官方预设包见子入口 `modern-text/deformations`。
|
|
180
|
+
*/
|
|
181
|
+
declare function defineDeformation(name: string, preset: DeformationPreset): void;
|
|
182
|
+
/** 取消注册某个预设 */
|
|
183
|
+
declare function removeDeformation(name: string): void;
|
|
184
|
+
/** 当前已注册的预设名列表 */
|
|
185
|
+
declare function getDeformationNames(): string[];
|
|
186
|
+
/**
|
|
187
|
+
* 文字变形插件(纯引擎)。
|
|
188
|
+
*
|
|
189
|
+
* 通过 `text.deformation` 指定**已注册**的预设名:
|
|
190
|
+
* ```ts
|
|
191
|
+
* import { registerDeformations } from 'modern-text/deformations'
|
|
192
|
+
* registerDeformations()
|
|
193
|
+
* new Text({ content: 'abc', deformation: { type: 'bend', intensities: [50] } })
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
declare function deformationPlugin(): Plugin;
|
|
197
|
+
|
|
18
198
|
declare function getHighlightStyle(style: NormalizedStyle): NormalizedHighlight;
|
|
19
199
|
declare function highlightPlugin(): Plugin;
|
|
20
200
|
|
|
@@ -60,5 +240,5 @@ declare function parseColormap(colormap: 'none' | Record<string, string>): Recor
|
|
|
60
240
|
declare function isEqualObject(obj1: Record<string, any>, obj2: Record<string, any>): boolean;
|
|
61
241
|
declare function isEqualValue(val1: any, val2: any): boolean;
|
|
62
242
|
|
|
63
|
-
export { MeasureResult, Options, Plugin, RenderOptions, Text, backgroundPlugin, createSvgLoader, createSvgParser, definePlugin, getEffectTransform2D, getHighlightStyle, highlightPlugin, isEqualObject, isEqualValue, listStylePlugin, measureText, outlinePlugin, parseColormap, parseTransformOrigin, parseValueNumber, renderPlugin, renderText, textDecorationPlugin };
|
|
243
|
+
export { Character, CircleCurve, DeformationPreset, EllipseCurve, FontMeasurer, HeartCurve, MeasureDomResult, MeasureResult, Options, Paragraph, Plugin, PolygonCurve, RectangularCurve, RenderOptions, Text, TextMeasurer, backgroundPlugin, createSvgLoader, createSvgParser, defineDeformation, definePlugin, deformationPlugin, getDeformationNames, getEffectTransform2D, getHighlightStyle, highlightPlugin, isEqualObject, isEqualValue, listStylePlugin, measureText, outlinePlugin, parseColormap, parseTransformOrigin, parseValueNumber, removeDeformation, renderPlugin, renderText, textDecorationPlugin };
|
|
64
244
|
export type { RenderTextOptions, SvgLoader, SvgParser };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,11 +1,72 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { C as Canvas2DRenderer,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import 'modern-
|
|
1
|
+
import { i as Plugin, k as TextMeasurer, P as Paragraph, M as MeasureDomResult, a as Character, O as Options, c as MeasureResult, R as RenderOptions, T as Text } from './shared/modern-text.D4WopQCu.mjs';
|
|
2
|
+
export { C as Canvas2DRenderer, D as DomMeasurer, b as DrawShapePathsOptions, F as Fragment, d as MeasuredCharacter, e as MeasuredCharacterRect, f as MeasuredFragment, g as MeasuredParagraph, h as MeasurerKind, j as TextEvents, t as textDefaultStyle } from './shared/modern-text.D4WopQCu.mjs';
|
|
3
|
+
import { Fonts } from 'modern-font';
|
|
4
|
+
import { FullStyle, NormalizedStyle, NormalizedHighlight, NormalizedEffect } from 'modern-idoc';
|
|
5
|
+
import { BoundingBox, Vector2, Path2DSet, Transform2D } from 'modern-path2d';
|
|
6
|
+
import { c as DeformationPreset } from './shared/modern-text.CYa4lfoG.mjs';
|
|
7
|
+
export { B as BendContext, a as BendPreset, C as CurvePreset, D as DeformationCharInfo, b as DeformationCurve, F as FfdContext, d as FfdPreset, O as OffsetPreset, V as VerbatimContext } from './shared/modern-text.CYa4lfoG.mjs';
|
|
6
8
|
|
|
7
9
|
declare function definePlugin(options: Plugin): Plugin;
|
|
8
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Pure-JS, DOM-free text measurer — a drop-in alternative to {@link DomMeasurer}.
|
|
13
|
+
*
|
|
14
|
+
* Instead of mounting a `<section>/<ul>/<li>/<span>` tree and reading
|
|
15
|
+
* `getBoundingClientRect()`, it computes the same four-level boxes
|
|
16
|
+
* (`character.inlineBox`/`lineBox`, `fragment.inlineBox`, `paragraph.lineBox`)
|
|
17
|
+
* from `modern-font` glyph advances, so the downstream
|
|
18
|
+
* measure → glyph → plugin pipeline is unchanged and it runs in Node/SSR/Worker.
|
|
19
|
+
*
|
|
20
|
+
* ## Scope
|
|
21
|
+
* - `horizontal-tb` (LTR) and `vertical-rl` (columns right-to-left, glyphs top↓)
|
|
22
|
+
* - line breaking: `word-break: break-all` (greedy, break anywhere) + explicit `\n`
|
|
23
|
+
* - per-line `text-align` (start/left/center/end/right), `text-indent` (first line)
|
|
24
|
+
* - box model: root + paragraph `padding`/`margin` (horizontal), `letter-spacing`,
|
|
25
|
+
* `line-height`; block `vertical-align` (top/middle/bottom) at fixed height
|
|
26
|
+
*
|
|
27
|
+
* ## Not yet implemented (TODO)
|
|
28
|
+
* - UAX#14 `word-break: normal` + 避头尾/kinsoku (`line-break`)
|
|
29
|
+
* - BiDi, per-fragment inline `vertical-align`, borders
|
|
30
|
+
* - vertical: per-paragraph margin/padding and block alignment
|
|
31
|
+
* - kerning/ligatures (GSUB/GPOS) — fine for CJK, diverges for proportional Latin
|
|
32
|
+
*
|
|
33
|
+
* Coordinates are relative to the root border-box top-left (matching the DOM
|
|
34
|
+
* measurer, whose rects are taken relative to `section.getBoundingClientRect()`).
|
|
35
|
+
*/
|
|
36
|
+
declare class FontMeasurer implements TextMeasurer {
|
|
37
|
+
measure(paragraphs: Paragraph[], rootStyle: FullStyle, _dom?: HTMLElement, fonts?: Fonts): MeasureDomResult;
|
|
38
|
+
protected _rootPadding(rootStyle: FullStyle): {
|
|
39
|
+
top: number;
|
|
40
|
+
right: number;
|
|
41
|
+
bottom: number;
|
|
42
|
+
left: number;
|
|
43
|
+
};
|
|
44
|
+
protected _measureHorizontal(paragraphs: Paragraph[], rootStyle: FullStyle): MeasureDomResult;
|
|
45
|
+
/**
|
|
46
|
+
* Vertical writing-mode (`vertical-rl`): columns stack right-to-left, glyphs
|
|
47
|
+
* flow top→bottom. It is the horizontal layout with the inline and block axes
|
|
48
|
+
* swapped — the inline (down-column) advance is `advanceWidth` (CJK upright = em;
|
|
49
|
+
* Latin is rotated, so its advance ≈ its width), the cross-axis content box is
|
|
50
|
+
* `advanceHeight`, and the column thickness is `fontHeight`. The lineBox is
|
|
51
|
+
* derived exactly as DomMeasurer.measureParagraphDom's vertical branch, so it
|
|
52
|
+
* stays accurate even though inlineBox carries the content-box rounding residual.
|
|
53
|
+
*
|
|
54
|
+
* v1: `vertical-rl` only; no per-paragraph margin/padding or block alignment.
|
|
55
|
+
*/
|
|
56
|
+
protected _measureVertical(paragraphs: Paragraph[], rootStyle: FullStyle): MeasureDomResult;
|
|
57
|
+
/** Advance step including CSS letter-spacing (px). */
|
|
58
|
+
protected _advance(character: Character): number;
|
|
59
|
+
/**
|
|
60
|
+
* Break a paragraph's characters into visual lines.
|
|
61
|
+
* v1: `word-break: break-all` (break before any character that would overflow)
|
|
62
|
+
* plus explicit `\n`/`\r` hard breaks. The newline itself occupies no line box.
|
|
63
|
+
*/
|
|
64
|
+
protected _breakLines(paragraph: Paragraph, avail: number): Character[][];
|
|
65
|
+
protected _unionInto(target: BoundingBox, boxes: BoundingBox[]): void;
|
|
66
|
+
protected _shiftAll(paragraphs: Paragraph[], dy: number): void;
|
|
67
|
+
dispose(): void;
|
|
68
|
+
}
|
|
69
|
+
|
|
9
70
|
declare function measureText(options: Options, load: true): Promise<MeasureResult>;
|
|
10
71
|
declare function measureText(options: Options): MeasureResult;
|
|
11
72
|
|
|
@@ -15,6 +76,125 @@ declare function renderText(options: RenderTextOptions): void;
|
|
|
15
76
|
|
|
16
77
|
declare function backgroundPlugin(): Plugin;
|
|
17
78
|
|
|
79
|
+
/**
|
|
80
|
+
* 这些曲线类用于「逐字(-by-word)」沿形状排布文字。
|
|
81
|
+
*
|
|
82
|
+
* 旧版变形代码针对 `modern-path2d@0.2.5` 编写,该版本内置了
|
|
83
|
+
* `CircleCurve` / `EllipseCurve` / `HeartCurve` / `PolygonCurve` / `RectangularCurve`,
|
|
84
|
+
* 当前版本(1.6.x)已不再导出。这里从 0.2.5 原样移植其实现,
|
|
85
|
+
* 仅做 Vector2 API 适配(`copy`→`copyFrom`、`new Vector2().lerpVectors`→`Vector2.lerp`),
|
|
86
|
+
* 以保证逐字排布效果与原版一致。
|
|
87
|
+
*
|
|
88
|
+
* 仅保留 deformer 实际用到的方法:getPoint / getPointAt / getTangent / getNormal。
|
|
89
|
+
*/
|
|
90
|
+
declare abstract class ShapeCurve {
|
|
91
|
+
arcLengthDivisions: number;
|
|
92
|
+
protected _cacheArcLengths?: number[];
|
|
93
|
+
protected _needsUpdate: boolean;
|
|
94
|
+
abstract getPoint(t: number, output?: Vector2): Vector2;
|
|
95
|
+
getPointAt(u: number, output?: Vector2): Vector2;
|
|
96
|
+
getLength(): number;
|
|
97
|
+
getLengths(divisions?: number): number[];
|
|
98
|
+
getUToTMapping(u: number, distance?: number): number;
|
|
99
|
+
getTangent(t: number, output?: Vector2): Vector2;
|
|
100
|
+
getNormal(t: number, output?: Vector2): Vector2;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 分段曲线基类:由若干子曲线拼成,`getCurve(t)` 选中子曲线并把 `curveT` 设为其局部参数,
|
|
104
|
+
* 其余取点/切线/法线统一委托给选中的子曲线。
|
|
105
|
+
*/
|
|
106
|
+
declare abstract class SegmentedCurve extends ShapeCurve {
|
|
107
|
+
protected curveT: number;
|
|
108
|
+
abstract getCurve(t: number): ShapeCurve;
|
|
109
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
110
|
+
getPointAt(u: number, output?: Vector2): Vector2;
|
|
111
|
+
getTangent(t: number, output?: Vector2): Vector2;
|
|
112
|
+
getNormal(t: number, output?: Vector2): Vector2;
|
|
113
|
+
}
|
|
114
|
+
declare class LineShapeCurve extends ShapeCurve {
|
|
115
|
+
start: Vector2;
|
|
116
|
+
end: Vector2;
|
|
117
|
+
constructor(start: Vector2, end: Vector2);
|
|
118
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
119
|
+
getPointAt(u: number, output?: Vector2): Vector2;
|
|
120
|
+
getTangent(_t: number, output?: Vector2): Vector2;
|
|
121
|
+
}
|
|
122
|
+
declare class CircleCurve extends ShapeCurve {
|
|
123
|
+
center: Vector2;
|
|
124
|
+
radius: number;
|
|
125
|
+
start: number;
|
|
126
|
+
end: number;
|
|
127
|
+
constructor(center: Vector2, radius: number, start?: number, end?: number);
|
|
128
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
129
|
+
getTangent(t: number, output?: Vector2): Vector2;
|
|
130
|
+
getNormal(t: number, output?: Vector2): Vector2;
|
|
131
|
+
}
|
|
132
|
+
declare class EllipseCurve extends ShapeCurve {
|
|
133
|
+
center: Vector2;
|
|
134
|
+
radiusX: number;
|
|
135
|
+
radiusY: number;
|
|
136
|
+
rotation: number;
|
|
137
|
+
startAngle: number;
|
|
138
|
+
endAngle: number;
|
|
139
|
+
clockwise: boolean;
|
|
140
|
+
constructor(center?: Vector2, radiusX?: number, radiusY?: number, rotation?: number, startAngle?: number, endAngle?: number, clockwise?: boolean);
|
|
141
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
142
|
+
}
|
|
143
|
+
declare class HeartCurve extends SegmentedCurve {
|
|
144
|
+
center: Vector2;
|
|
145
|
+
size: number;
|
|
146
|
+
start: number;
|
|
147
|
+
end: number;
|
|
148
|
+
protected curves: ShapeCurve[];
|
|
149
|
+
constructor(center: Vector2, size: number, start?: number, end?: number);
|
|
150
|
+
update(): this;
|
|
151
|
+
getCurve(t: number): ShapeCurve;
|
|
152
|
+
}
|
|
153
|
+
declare class PolygonCurve extends SegmentedCurve {
|
|
154
|
+
center: Vector2;
|
|
155
|
+
radius: number;
|
|
156
|
+
number: number;
|
|
157
|
+
start: number;
|
|
158
|
+
end: number;
|
|
159
|
+
protected curves: LineShapeCurve[];
|
|
160
|
+
protected points: Vector2[];
|
|
161
|
+
constructor(center: Vector2, radius?: number, number?: number, start?: number, end?: number);
|
|
162
|
+
update(): this;
|
|
163
|
+
getCurve(t: number): LineShapeCurve;
|
|
164
|
+
}
|
|
165
|
+
declare class RectangularCurve extends SegmentedCurve {
|
|
166
|
+
center: Vector2;
|
|
167
|
+
rx: number;
|
|
168
|
+
aspectRatio: number;
|
|
169
|
+
start: number;
|
|
170
|
+
end: number;
|
|
171
|
+
protected curves: LineShapeCurve[];
|
|
172
|
+
constructor(center: Vector2, rx: number, aspectRatio?: number, start?: number, end?: number);
|
|
173
|
+
update(): this;
|
|
174
|
+
getCurve(t: number): LineShapeCurve;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* 注册一个变形预设(库外部定义,运行时透传)。
|
|
179
|
+
* 官方预设包见子入口 `modern-text/deformations`。
|
|
180
|
+
*/
|
|
181
|
+
declare function defineDeformation(name: string, preset: DeformationPreset): void;
|
|
182
|
+
/** 取消注册某个预设 */
|
|
183
|
+
declare function removeDeformation(name: string): void;
|
|
184
|
+
/** 当前已注册的预设名列表 */
|
|
185
|
+
declare function getDeformationNames(): string[];
|
|
186
|
+
/**
|
|
187
|
+
* 文字变形插件(纯引擎)。
|
|
188
|
+
*
|
|
189
|
+
* 通过 `text.deformation` 指定**已注册**的预设名:
|
|
190
|
+
* ```ts
|
|
191
|
+
* import { registerDeformations } from 'modern-text/deformations'
|
|
192
|
+
* registerDeformations()
|
|
193
|
+
* new Text({ content: 'abc', deformation: { type: 'bend', intensities: [50] } })
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
declare function deformationPlugin(): Plugin;
|
|
197
|
+
|
|
18
198
|
declare function getHighlightStyle(style: NormalizedStyle): NormalizedHighlight;
|
|
19
199
|
declare function highlightPlugin(): Plugin;
|
|
20
200
|
|
|
@@ -60,5 +240,5 @@ declare function parseColormap(colormap: 'none' | Record<string, string>): Recor
|
|
|
60
240
|
declare function isEqualObject(obj1: Record<string, any>, obj2: Record<string, any>): boolean;
|
|
61
241
|
declare function isEqualValue(val1: any, val2: any): boolean;
|
|
62
242
|
|
|
63
|
-
export { MeasureResult, Options, Plugin, RenderOptions, Text, backgroundPlugin, createSvgLoader, createSvgParser, definePlugin, getEffectTransform2D, getHighlightStyle, highlightPlugin, isEqualObject, isEqualValue, listStylePlugin, measureText, outlinePlugin, parseColormap, parseTransformOrigin, parseValueNumber, renderPlugin, renderText, textDecorationPlugin };
|
|
243
|
+
export { Character, CircleCurve, DeformationPreset, EllipseCurve, FontMeasurer, HeartCurve, MeasureDomResult, MeasureResult, Options, Paragraph, Plugin, PolygonCurve, RectangularCurve, RenderOptions, Text, TextMeasurer, backgroundPlugin, createSvgLoader, createSvgParser, defineDeformation, definePlugin, deformationPlugin, getDeformationNames, getEffectTransform2D, getHighlightStyle, highlightPlugin, isEqualObject, isEqualValue, listStylePlugin, measureText, outlinePlugin, parseColormap, parseTransformOrigin, parseValueNumber, removeDeformation, renderPlugin, renderText, textDecorationPlugin };
|
|
64
244
|
export type { RenderTextOptions, SvgLoader, SvgParser };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,72 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { C as Canvas2DRenderer,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import 'modern-
|
|
1
|
+
import { i as Plugin, k as TextMeasurer, P as Paragraph, M as MeasureDomResult, a as Character, O as Options, c as MeasureResult, R as RenderOptions, T as Text } from './shared/modern-text.D4WopQCu.js';
|
|
2
|
+
export { C as Canvas2DRenderer, D as DomMeasurer, b as DrawShapePathsOptions, F as Fragment, d as MeasuredCharacter, e as MeasuredCharacterRect, f as MeasuredFragment, g as MeasuredParagraph, h as MeasurerKind, j as TextEvents, t as textDefaultStyle } from './shared/modern-text.D4WopQCu.js';
|
|
3
|
+
import { Fonts } from 'modern-font';
|
|
4
|
+
import { FullStyle, NormalizedStyle, NormalizedHighlight, NormalizedEffect } from 'modern-idoc';
|
|
5
|
+
import { BoundingBox, Vector2, Path2DSet, Transform2D } from 'modern-path2d';
|
|
6
|
+
import { c as DeformationPreset } from './shared/modern-text.BxijkspX.js';
|
|
7
|
+
export { B as BendContext, a as BendPreset, C as CurvePreset, D as DeformationCharInfo, b as DeformationCurve, F as FfdContext, d as FfdPreset, O as OffsetPreset, V as VerbatimContext } from './shared/modern-text.BxijkspX.js';
|
|
6
8
|
|
|
7
9
|
declare function definePlugin(options: Plugin): Plugin;
|
|
8
10
|
|
|
11
|
+
/**
|
|
12
|
+
* Pure-JS, DOM-free text measurer — a drop-in alternative to {@link DomMeasurer}.
|
|
13
|
+
*
|
|
14
|
+
* Instead of mounting a `<section>/<ul>/<li>/<span>` tree and reading
|
|
15
|
+
* `getBoundingClientRect()`, it computes the same four-level boxes
|
|
16
|
+
* (`character.inlineBox`/`lineBox`, `fragment.inlineBox`, `paragraph.lineBox`)
|
|
17
|
+
* from `modern-font` glyph advances, so the downstream
|
|
18
|
+
* measure → glyph → plugin pipeline is unchanged and it runs in Node/SSR/Worker.
|
|
19
|
+
*
|
|
20
|
+
* ## Scope
|
|
21
|
+
* - `horizontal-tb` (LTR) and `vertical-rl` (columns right-to-left, glyphs top↓)
|
|
22
|
+
* - line breaking: `word-break: break-all` (greedy, break anywhere) + explicit `\n`
|
|
23
|
+
* - per-line `text-align` (start/left/center/end/right), `text-indent` (first line)
|
|
24
|
+
* - box model: root + paragraph `padding`/`margin` (horizontal), `letter-spacing`,
|
|
25
|
+
* `line-height`; block `vertical-align` (top/middle/bottom) at fixed height
|
|
26
|
+
*
|
|
27
|
+
* ## Not yet implemented (TODO)
|
|
28
|
+
* - UAX#14 `word-break: normal` + 避头尾/kinsoku (`line-break`)
|
|
29
|
+
* - BiDi, per-fragment inline `vertical-align`, borders
|
|
30
|
+
* - vertical: per-paragraph margin/padding and block alignment
|
|
31
|
+
* - kerning/ligatures (GSUB/GPOS) — fine for CJK, diverges for proportional Latin
|
|
32
|
+
*
|
|
33
|
+
* Coordinates are relative to the root border-box top-left (matching the DOM
|
|
34
|
+
* measurer, whose rects are taken relative to `section.getBoundingClientRect()`).
|
|
35
|
+
*/
|
|
36
|
+
declare class FontMeasurer implements TextMeasurer {
|
|
37
|
+
measure(paragraphs: Paragraph[], rootStyle: FullStyle, _dom?: HTMLElement, fonts?: Fonts): MeasureDomResult;
|
|
38
|
+
protected _rootPadding(rootStyle: FullStyle): {
|
|
39
|
+
top: number;
|
|
40
|
+
right: number;
|
|
41
|
+
bottom: number;
|
|
42
|
+
left: number;
|
|
43
|
+
};
|
|
44
|
+
protected _measureHorizontal(paragraphs: Paragraph[], rootStyle: FullStyle): MeasureDomResult;
|
|
45
|
+
/**
|
|
46
|
+
* Vertical writing-mode (`vertical-rl`): columns stack right-to-left, glyphs
|
|
47
|
+
* flow top→bottom. It is the horizontal layout with the inline and block axes
|
|
48
|
+
* swapped — the inline (down-column) advance is `advanceWidth` (CJK upright = em;
|
|
49
|
+
* Latin is rotated, so its advance ≈ its width), the cross-axis content box is
|
|
50
|
+
* `advanceHeight`, and the column thickness is `fontHeight`. The lineBox is
|
|
51
|
+
* derived exactly as DomMeasurer.measureParagraphDom's vertical branch, so it
|
|
52
|
+
* stays accurate even though inlineBox carries the content-box rounding residual.
|
|
53
|
+
*
|
|
54
|
+
* v1: `vertical-rl` only; no per-paragraph margin/padding or block alignment.
|
|
55
|
+
*/
|
|
56
|
+
protected _measureVertical(paragraphs: Paragraph[], rootStyle: FullStyle): MeasureDomResult;
|
|
57
|
+
/** Advance step including CSS letter-spacing (px). */
|
|
58
|
+
protected _advance(character: Character): number;
|
|
59
|
+
/**
|
|
60
|
+
* Break a paragraph's characters into visual lines.
|
|
61
|
+
* v1: `word-break: break-all` (break before any character that would overflow)
|
|
62
|
+
* plus explicit `\n`/`\r` hard breaks. The newline itself occupies no line box.
|
|
63
|
+
*/
|
|
64
|
+
protected _breakLines(paragraph: Paragraph, avail: number): Character[][];
|
|
65
|
+
protected _unionInto(target: BoundingBox, boxes: BoundingBox[]): void;
|
|
66
|
+
protected _shiftAll(paragraphs: Paragraph[], dy: number): void;
|
|
67
|
+
dispose(): void;
|
|
68
|
+
}
|
|
69
|
+
|
|
9
70
|
declare function measureText(options: Options, load: true): Promise<MeasureResult>;
|
|
10
71
|
declare function measureText(options: Options): MeasureResult;
|
|
11
72
|
|
|
@@ -15,6 +76,125 @@ declare function renderText(options: RenderTextOptions): void;
|
|
|
15
76
|
|
|
16
77
|
declare function backgroundPlugin(): Plugin;
|
|
17
78
|
|
|
79
|
+
/**
|
|
80
|
+
* 这些曲线类用于「逐字(-by-word)」沿形状排布文字。
|
|
81
|
+
*
|
|
82
|
+
* 旧版变形代码针对 `modern-path2d@0.2.5` 编写,该版本内置了
|
|
83
|
+
* `CircleCurve` / `EllipseCurve` / `HeartCurve` / `PolygonCurve` / `RectangularCurve`,
|
|
84
|
+
* 当前版本(1.6.x)已不再导出。这里从 0.2.5 原样移植其实现,
|
|
85
|
+
* 仅做 Vector2 API 适配(`copy`→`copyFrom`、`new Vector2().lerpVectors`→`Vector2.lerp`),
|
|
86
|
+
* 以保证逐字排布效果与原版一致。
|
|
87
|
+
*
|
|
88
|
+
* 仅保留 deformer 实际用到的方法:getPoint / getPointAt / getTangent / getNormal。
|
|
89
|
+
*/
|
|
90
|
+
declare abstract class ShapeCurve {
|
|
91
|
+
arcLengthDivisions: number;
|
|
92
|
+
protected _cacheArcLengths?: number[];
|
|
93
|
+
protected _needsUpdate: boolean;
|
|
94
|
+
abstract getPoint(t: number, output?: Vector2): Vector2;
|
|
95
|
+
getPointAt(u: number, output?: Vector2): Vector2;
|
|
96
|
+
getLength(): number;
|
|
97
|
+
getLengths(divisions?: number): number[];
|
|
98
|
+
getUToTMapping(u: number, distance?: number): number;
|
|
99
|
+
getTangent(t: number, output?: Vector2): Vector2;
|
|
100
|
+
getNormal(t: number, output?: Vector2): Vector2;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* 分段曲线基类:由若干子曲线拼成,`getCurve(t)` 选中子曲线并把 `curveT` 设为其局部参数,
|
|
104
|
+
* 其余取点/切线/法线统一委托给选中的子曲线。
|
|
105
|
+
*/
|
|
106
|
+
declare abstract class SegmentedCurve extends ShapeCurve {
|
|
107
|
+
protected curveT: number;
|
|
108
|
+
abstract getCurve(t: number): ShapeCurve;
|
|
109
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
110
|
+
getPointAt(u: number, output?: Vector2): Vector2;
|
|
111
|
+
getTangent(t: number, output?: Vector2): Vector2;
|
|
112
|
+
getNormal(t: number, output?: Vector2): Vector2;
|
|
113
|
+
}
|
|
114
|
+
declare class LineShapeCurve extends ShapeCurve {
|
|
115
|
+
start: Vector2;
|
|
116
|
+
end: Vector2;
|
|
117
|
+
constructor(start: Vector2, end: Vector2);
|
|
118
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
119
|
+
getPointAt(u: number, output?: Vector2): Vector2;
|
|
120
|
+
getTangent(_t: number, output?: Vector2): Vector2;
|
|
121
|
+
}
|
|
122
|
+
declare class CircleCurve extends ShapeCurve {
|
|
123
|
+
center: Vector2;
|
|
124
|
+
radius: number;
|
|
125
|
+
start: number;
|
|
126
|
+
end: number;
|
|
127
|
+
constructor(center: Vector2, radius: number, start?: number, end?: number);
|
|
128
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
129
|
+
getTangent(t: number, output?: Vector2): Vector2;
|
|
130
|
+
getNormal(t: number, output?: Vector2): Vector2;
|
|
131
|
+
}
|
|
132
|
+
declare class EllipseCurve extends ShapeCurve {
|
|
133
|
+
center: Vector2;
|
|
134
|
+
radiusX: number;
|
|
135
|
+
radiusY: number;
|
|
136
|
+
rotation: number;
|
|
137
|
+
startAngle: number;
|
|
138
|
+
endAngle: number;
|
|
139
|
+
clockwise: boolean;
|
|
140
|
+
constructor(center?: Vector2, radiusX?: number, radiusY?: number, rotation?: number, startAngle?: number, endAngle?: number, clockwise?: boolean);
|
|
141
|
+
getPoint(t: number, output?: Vector2): Vector2;
|
|
142
|
+
}
|
|
143
|
+
declare class HeartCurve extends SegmentedCurve {
|
|
144
|
+
center: Vector2;
|
|
145
|
+
size: number;
|
|
146
|
+
start: number;
|
|
147
|
+
end: number;
|
|
148
|
+
protected curves: ShapeCurve[];
|
|
149
|
+
constructor(center: Vector2, size: number, start?: number, end?: number);
|
|
150
|
+
update(): this;
|
|
151
|
+
getCurve(t: number): ShapeCurve;
|
|
152
|
+
}
|
|
153
|
+
declare class PolygonCurve extends SegmentedCurve {
|
|
154
|
+
center: Vector2;
|
|
155
|
+
radius: number;
|
|
156
|
+
number: number;
|
|
157
|
+
start: number;
|
|
158
|
+
end: number;
|
|
159
|
+
protected curves: LineShapeCurve[];
|
|
160
|
+
protected points: Vector2[];
|
|
161
|
+
constructor(center: Vector2, radius?: number, number?: number, start?: number, end?: number);
|
|
162
|
+
update(): this;
|
|
163
|
+
getCurve(t: number): LineShapeCurve;
|
|
164
|
+
}
|
|
165
|
+
declare class RectangularCurve extends SegmentedCurve {
|
|
166
|
+
center: Vector2;
|
|
167
|
+
rx: number;
|
|
168
|
+
aspectRatio: number;
|
|
169
|
+
start: number;
|
|
170
|
+
end: number;
|
|
171
|
+
protected curves: LineShapeCurve[];
|
|
172
|
+
constructor(center: Vector2, rx: number, aspectRatio?: number, start?: number, end?: number);
|
|
173
|
+
update(): this;
|
|
174
|
+
getCurve(t: number): LineShapeCurve;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* 注册一个变形预设(库外部定义,运行时透传)。
|
|
179
|
+
* 官方预设包见子入口 `modern-text/deformations`。
|
|
180
|
+
*/
|
|
181
|
+
declare function defineDeformation(name: string, preset: DeformationPreset): void;
|
|
182
|
+
/** 取消注册某个预设 */
|
|
183
|
+
declare function removeDeformation(name: string): void;
|
|
184
|
+
/** 当前已注册的预设名列表 */
|
|
185
|
+
declare function getDeformationNames(): string[];
|
|
186
|
+
/**
|
|
187
|
+
* 文字变形插件(纯引擎)。
|
|
188
|
+
*
|
|
189
|
+
* 通过 `text.deformation` 指定**已注册**的预设名:
|
|
190
|
+
* ```ts
|
|
191
|
+
* import { registerDeformations } from 'modern-text/deformations'
|
|
192
|
+
* registerDeformations()
|
|
193
|
+
* new Text({ content: 'abc', deformation: { type: 'bend', intensities: [50] } })
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
declare function deformationPlugin(): Plugin;
|
|
197
|
+
|
|
18
198
|
declare function getHighlightStyle(style: NormalizedStyle): NormalizedHighlight;
|
|
19
199
|
declare function highlightPlugin(): Plugin;
|
|
20
200
|
|
|
@@ -60,5 +240,5 @@ declare function parseColormap(colormap: 'none' | Record<string, string>): Recor
|
|
|
60
240
|
declare function isEqualObject(obj1: Record<string, any>, obj2: Record<string, any>): boolean;
|
|
61
241
|
declare function isEqualValue(val1: any, val2: any): boolean;
|
|
62
242
|
|
|
63
|
-
export { MeasureResult, Options, Plugin, RenderOptions, Text, backgroundPlugin, createSvgLoader, createSvgParser, definePlugin, getEffectTransform2D, getHighlightStyle, highlightPlugin, isEqualObject, isEqualValue, listStylePlugin, measureText, outlinePlugin, parseColormap, parseTransformOrigin, parseValueNumber, renderPlugin, renderText, textDecorationPlugin };
|
|
243
|
+
export { Character, CircleCurve, DeformationPreset, EllipseCurve, FontMeasurer, HeartCurve, MeasureDomResult, MeasureResult, Options, Paragraph, Plugin, PolygonCurve, RectangularCurve, RenderOptions, Text, TextMeasurer, backgroundPlugin, createSvgLoader, createSvgParser, defineDeformation, definePlugin, deformationPlugin, getDeformationNames, getEffectTransform2D, getHighlightStyle, highlightPlugin, isEqualObject, isEqualValue, listStylePlugin, measureText, outlinePlugin, parseColormap, parseTransformOrigin, parseValueNumber, removeDeformation, renderPlugin, renderText, textDecorationPlugin };
|
|
64
244
|
export type { RenderTextOptions, SvgLoader, SvgParser };
|