three-text 0.1.1 → 0.2.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 +166 -156
- package/dist/index.cjs +370 -81
- package/dist/index.d.ts +46 -17
- package/dist/index.js +369 -80
- package/dist/index.min.cjs +2 -2
- package/dist/index.min.js +2 -2
- package/dist/index.umd.js +374 -83
- package/dist/index.umd.min.js +2 -2
- package/dist/p5/index.cjs +33 -0
- package/dist/p5/index.d.ts +19 -0
- package/dist/p5/index.js +31 -0
- package/dist/three/index.cjs +50 -0
- package/dist/three/index.d.ts +29 -0
- package/dist/three/index.js +48 -0
- package/dist/{react/index.cjs → three/react.cjs} +14 -4
- package/dist/three/react.d.ts +346 -0
- package/dist/{react/index.js → three/react.js} +14 -4
- package/dist/types/core/Text.d.ts +1 -1
- package/dist/types/core/cache/GlyphCache.d.ts +4 -4
- package/dist/types/core/cache/GlyphContourCollector.d.ts +2 -2
- package/dist/types/core/cache/GlyphGeometryBuilder.d.ts +3 -2
- package/dist/types/core/geometry/BoundaryClusterer.d.ts +2 -2
- package/dist/types/core/geometry/Polygonizer.d.ts +3 -3
- package/dist/types/core/layout/TextLayout.d.ts +1 -2
- package/dist/types/core/shaping/TextShaper.d.ts +1 -2
- package/dist/types/core/types.d.ts +13 -16
- package/dist/types/core/vectors.d.ts +75 -0
- package/dist/types/p5/index.d.ts +17 -0
- package/dist/types/{react → three}/ThreeText.d.ts +2 -2
- package/dist/types/three/index.d.ts +21 -0
- package/dist/types/three/react.d.ts +10 -0
- package/dist/types/webgl/index.d.ts +48 -0
- package/dist/types/webgpu/index.d.ts +16 -0
- package/dist/webgl/index.cjs +88 -0
- package/dist/webgl/index.d.ts +51 -0
- package/dist/webgl/index.js +86 -0
- package/dist/webgpu/index.cjs +99 -0
- package/dist/webgpu/index.d.ts +19 -0
- package/dist/webgpu/index.js +97 -0
- package/package.json +22 -6
- package/dist/react/index.d.ts +0 -18
- package/dist/types/react/index.d.ts +0 -2
package/dist/p5/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// p5.js adapter - converts core geometry to p5.Geometry
|
|
2
|
+
function createP5Geometry(p5Instance, textGeometry) {
|
|
3
|
+
// In global mode, p5.Geometry exists but createVector is global
|
|
4
|
+
// In instance mode, both are on the instance
|
|
5
|
+
const P5Geometry = p5Instance.Geometry || window.p5?.Geometry;
|
|
6
|
+
const createVec = p5Instance.createVector || window.createVector;
|
|
7
|
+
if (!P5Geometry || !createVec) {
|
|
8
|
+
throw new Error('p5.js not found. Make sure p5.js is loaded before calling this function.');
|
|
9
|
+
}
|
|
10
|
+
const geom = new P5Geometry();
|
|
11
|
+
const { vertices, normals, indices } = textGeometry;
|
|
12
|
+
// Convert vertices (flip Y for p5.js coordinate system)
|
|
13
|
+
for (let i = 0; i < vertices.length; i += 3) {
|
|
14
|
+
geom.vertices.push(createVec(vertices[i], -vertices[i + 1], vertices[i + 2]));
|
|
15
|
+
}
|
|
16
|
+
// Convert normals (flip Y)
|
|
17
|
+
for (let i = 0; i < normals.length; i += 3) {
|
|
18
|
+
geom.vertexNormals.push(createVec(normals[i], -normals[i + 1], normals[i + 2]));
|
|
19
|
+
}
|
|
20
|
+
// Convert indices to faces
|
|
21
|
+
for (let i = 0; i < indices.length; i += 3) {
|
|
22
|
+
geom.faces.push([
|
|
23
|
+
indices[i],
|
|
24
|
+
indices[i + 1],
|
|
25
|
+
indices[i + 2]
|
|
26
|
+
]);
|
|
27
|
+
}
|
|
28
|
+
return geom;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export { createP5Geometry };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var three = require('three');
|
|
4
|
+
var Text$1 = require('../index.cjs');
|
|
5
|
+
|
|
6
|
+
// Three.js adapter - wraps core text processing and returns BufferGeometry
|
|
7
|
+
// This is a thin convenience layer for Three.js users
|
|
8
|
+
class Text {
|
|
9
|
+
// Delegate static methods to core
|
|
10
|
+
static { this.setHarfBuzzPath = Text$1.Text.setHarfBuzzPath; }
|
|
11
|
+
static { this.setHarfBuzzBuffer = Text$1.Text.setHarfBuzzBuffer; }
|
|
12
|
+
static { this.init = Text$1.Text.init; }
|
|
13
|
+
static { this.registerPattern = Text$1.Text.registerPattern; }
|
|
14
|
+
static { this.preloadPatterns = Text$1.Text.preloadPatterns; }
|
|
15
|
+
// Main API - wraps core result in BufferGeometry
|
|
16
|
+
static async create(options) {
|
|
17
|
+
const coreResult = await Text$1.Text.create(options);
|
|
18
|
+
// Create BufferGeometry from raw arrays
|
|
19
|
+
const geometry = new three.BufferGeometry();
|
|
20
|
+
geometry.setAttribute('position', new three.Float32BufferAttribute(coreResult.vertices, 3));
|
|
21
|
+
geometry.setAttribute('normal', new three.Float32BufferAttribute(coreResult.normals, 3));
|
|
22
|
+
geometry.setIndex(Array.from(coreResult.indices));
|
|
23
|
+
// Add optional attributes
|
|
24
|
+
if (coreResult.colors) {
|
|
25
|
+
geometry.setAttribute('color', new three.Float32BufferAttribute(coreResult.colors, 3));
|
|
26
|
+
}
|
|
27
|
+
if (coreResult.glyphAttributes) {
|
|
28
|
+
geometry.setAttribute('glyphCenter', new three.Float32BufferAttribute(coreResult.glyphAttributes.glyphCenter, 3));
|
|
29
|
+
geometry.setAttribute('glyphIndex', new three.Float32BufferAttribute(coreResult.glyphAttributes.glyphIndex, 1));
|
|
30
|
+
geometry.setAttribute('glyphLineIndex', new three.Float32BufferAttribute(coreResult.glyphAttributes.glyphLineIndex, 1));
|
|
31
|
+
}
|
|
32
|
+
geometry.computeBoundingBox();
|
|
33
|
+
// Return Three.js specific interface with utility methods
|
|
34
|
+
return {
|
|
35
|
+
geometry,
|
|
36
|
+
glyphs: coreResult.glyphs,
|
|
37
|
+
planeBounds: coreResult.planeBounds,
|
|
38
|
+
stats: coreResult.stats,
|
|
39
|
+
query: coreResult.query,
|
|
40
|
+
coloredRanges: coreResult.coloredRanges,
|
|
41
|
+
// Pass through utility methods from core
|
|
42
|
+
getLoadedFont: coreResult.getLoadedFont,
|
|
43
|
+
getCacheStatistics: coreResult.getCacheStatistics,
|
|
44
|
+
clearCache: coreResult.clearCache,
|
|
45
|
+
measureTextWidth: coreResult.measureTextWidth
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
exports.Text = Text;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { BufferGeometry } from 'three';
|
|
2
|
+
import { Text as Text$1 } from '../core/Text';
|
|
3
|
+
import { TextGeometryInfo, LoadedFont, TextOptions } from '../core/types';
|
|
4
|
+
export { LoadedFont, TextOptions } from '../core/types';
|
|
5
|
+
|
|
6
|
+
interface HyphenationTrieNode {
|
|
7
|
+
patterns: number[] | null;
|
|
8
|
+
children: {
|
|
9
|
+
[char: string]: HyphenationTrieNode;
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface ThreeTextGeometryInfo extends Omit<TextGeometryInfo, 'vertices' | 'normals' | 'indices' | 'colors' | 'glyphAttributes'> {
|
|
14
|
+
geometry: BufferGeometry;
|
|
15
|
+
getLoadedFont(): LoadedFont | undefined;
|
|
16
|
+
getCacheStatistics(): any;
|
|
17
|
+
clearCache(): void;
|
|
18
|
+
measureTextWidth(text: string, letterSpacing?: number): number;
|
|
19
|
+
}
|
|
20
|
+
declare class Text {
|
|
21
|
+
static setHarfBuzzPath: typeof Text$1.setHarfBuzzPath;
|
|
22
|
+
static setHarfBuzzBuffer: typeof Text$1.setHarfBuzzBuffer;
|
|
23
|
+
static init: typeof Text$1.init;
|
|
24
|
+
static registerPattern: typeof Text$1.registerPattern;
|
|
25
|
+
static preloadPatterns: typeof Text$1.preloadPatterns;
|
|
26
|
+
static create(options: TextOptions): Promise<ThreeTextGeometryInfo>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { HyphenationTrieNode, Text, ThreeTextGeometryInfo as TextGeometryInfo, ThreeTextGeometryInfo };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { BufferGeometry, Float32BufferAttribute } from 'three';
|
|
2
|
+
import { Text as Text$1 } from '../index.js';
|
|
3
|
+
|
|
4
|
+
// Three.js adapter - wraps core text processing and returns BufferGeometry
|
|
5
|
+
// This is a thin convenience layer for Three.js users
|
|
6
|
+
class Text {
|
|
7
|
+
// Delegate static methods to core
|
|
8
|
+
static { this.setHarfBuzzPath = Text$1.setHarfBuzzPath; }
|
|
9
|
+
static { this.setHarfBuzzBuffer = Text$1.setHarfBuzzBuffer; }
|
|
10
|
+
static { this.init = Text$1.init; }
|
|
11
|
+
static { this.registerPattern = Text$1.registerPattern; }
|
|
12
|
+
static { this.preloadPatterns = Text$1.preloadPatterns; }
|
|
13
|
+
// Main API - wraps core result in BufferGeometry
|
|
14
|
+
static async create(options) {
|
|
15
|
+
const coreResult = await Text$1.create(options);
|
|
16
|
+
// Create BufferGeometry from raw arrays
|
|
17
|
+
const geometry = new BufferGeometry();
|
|
18
|
+
geometry.setAttribute('position', new Float32BufferAttribute(coreResult.vertices, 3));
|
|
19
|
+
geometry.setAttribute('normal', new Float32BufferAttribute(coreResult.normals, 3));
|
|
20
|
+
geometry.setIndex(Array.from(coreResult.indices));
|
|
21
|
+
// Add optional attributes
|
|
22
|
+
if (coreResult.colors) {
|
|
23
|
+
geometry.setAttribute('color', new Float32BufferAttribute(coreResult.colors, 3));
|
|
24
|
+
}
|
|
25
|
+
if (coreResult.glyphAttributes) {
|
|
26
|
+
geometry.setAttribute('glyphCenter', new Float32BufferAttribute(coreResult.glyphAttributes.glyphCenter, 3));
|
|
27
|
+
geometry.setAttribute('glyphIndex', new Float32BufferAttribute(coreResult.glyphAttributes.glyphIndex, 1));
|
|
28
|
+
geometry.setAttribute('glyphLineIndex', new Float32BufferAttribute(coreResult.glyphAttributes.glyphLineIndex, 1));
|
|
29
|
+
}
|
|
30
|
+
geometry.computeBoundingBox();
|
|
31
|
+
// Return Three.js specific interface with utility methods
|
|
32
|
+
return {
|
|
33
|
+
geometry,
|
|
34
|
+
glyphs: coreResult.glyphs,
|
|
35
|
+
planeBounds: coreResult.planeBounds,
|
|
36
|
+
stats: coreResult.stats,
|
|
37
|
+
query: coreResult.query,
|
|
38
|
+
coloredRanges: coreResult.coloredRanges,
|
|
39
|
+
// Pass through utility methods from core
|
|
40
|
+
getLoadedFont: coreResult.getLoadedFont,
|
|
41
|
+
getCacheStatistics: coreResult.getCacheStatistics,
|
|
42
|
+
clearCache: coreResult.clearCache,
|
|
43
|
+
measureTextWidth: coreResult.measureTextWidth
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export { Text };
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var THREE = require('three');
|
|
6
|
-
var
|
|
6
|
+
var index = require('./index');
|
|
7
7
|
|
|
8
8
|
function _interopNamespaceDefault(e) {
|
|
9
9
|
var n = Object.create(null);
|
|
@@ -50,7 +50,7 @@ function useDeepCompareMemo(value) {
|
|
|
50
50
|
}
|
|
51
51
|
return ref.current;
|
|
52
52
|
}
|
|
53
|
-
const
|
|
53
|
+
const Text$1 = react.forwardRef(function Text(props, ref) {
|
|
54
54
|
const { children, font, material, position = [0, 0, 0], rotation = [0, 0, 0], scale = [1, 1, 1], onLoad, onError, vertexColors = true, ...restOptions } = props;
|
|
55
55
|
const [geometry, setGeometry] = react.useState(null);
|
|
56
56
|
const [error, setError] = react.useState(null);
|
|
@@ -67,7 +67,7 @@ const ThreeText = react.forwardRef(function ThreeText(props, ref) {
|
|
|
67
67
|
setError(null);
|
|
68
68
|
if (cancelled)
|
|
69
69
|
return;
|
|
70
|
-
const text = await
|
|
70
|
+
const text = await index.Text.create({
|
|
71
71
|
text: children,
|
|
72
72
|
font,
|
|
73
73
|
...memoizedTextOptions,
|
|
@@ -118,4 +118,14 @@ const ThreeText = react.forwardRef(function ThreeText(props, ref) {
|
|
|
118
118
|
return (jsxRuntime.jsx("mesh", { ref: ref, geometry: geometry, material: finalMaterial, position: position, rotation: rotation, scale: scale }));
|
|
119
119
|
});
|
|
120
120
|
|
|
121
|
-
|
|
121
|
+
// Attach static methods from ThreeText to the React component
|
|
122
|
+
const Text = Object.assign(Text$1, {
|
|
123
|
+
setHarfBuzzPath: index.Text.setHarfBuzzPath,
|
|
124
|
+
setHarfBuzzBuffer: index.Text.setHarfBuzzBuffer,
|
|
125
|
+
init: index.Text.init,
|
|
126
|
+
registerPattern: index.Text.registerPattern,
|
|
127
|
+
preloadPatterns: index.Text.preloadPatterns,
|
|
128
|
+
create: index.Text.create
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
exports.Text = Text;
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import * as THREE from 'three';
|
|
3
|
+
import { TextOptions as TextOptions$1, ThreeTextGeometryInfo, Text as Text$2 } from './index';
|
|
4
|
+
|
|
5
|
+
interface BoundingBox {
|
|
6
|
+
min: {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
z: number;
|
|
10
|
+
};
|
|
11
|
+
max: {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
z: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface HyphenationTrieNode {
|
|
19
|
+
patterns: number[] | null;
|
|
20
|
+
children: {
|
|
21
|
+
[char: string]: HyphenationTrieNode;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type TextAlign = 'left' | 'center' | 'right' | 'justify';
|
|
26
|
+
type TextDirection = 'ltr' | 'rtl';
|
|
27
|
+
interface LoadedFont {
|
|
28
|
+
hb: HarfBuzzAPI;
|
|
29
|
+
fontBlob: HarfBuzzBlob;
|
|
30
|
+
face: HarfBuzzFace;
|
|
31
|
+
font: HarfBuzzFont;
|
|
32
|
+
module: HarfBuzzModule;
|
|
33
|
+
upem: number;
|
|
34
|
+
metrics: ExtractedMetrics;
|
|
35
|
+
fontVariations?: {
|
|
36
|
+
[key: string]: number;
|
|
37
|
+
};
|
|
38
|
+
isVariable?: boolean;
|
|
39
|
+
variationAxes?: {
|
|
40
|
+
[key: string]: VariationAxis;
|
|
41
|
+
};
|
|
42
|
+
_buffer?: ArrayBuffer;
|
|
43
|
+
}
|
|
44
|
+
interface HarfBuzzModule {
|
|
45
|
+
addFunction: (func: Function, signature: string) => number;
|
|
46
|
+
exports: any;
|
|
47
|
+
removeFunction: (ptr: number) => void;
|
|
48
|
+
}
|
|
49
|
+
interface VariationAxis {
|
|
50
|
+
min: number;
|
|
51
|
+
default: number;
|
|
52
|
+
max: number;
|
|
53
|
+
name?: string;
|
|
54
|
+
}
|
|
55
|
+
interface HarfBuzzAPI {
|
|
56
|
+
createBlob: (data: Uint8Array) => HarfBuzzBlob;
|
|
57
|
+
createFace: (blob: HarfBuzzBlob, index: number) => HarfBuzzFace;
|
|
58
|
+
createFont: (face: HarfBuzzFace) => HarfBuzzFont;
|
|
59
|
+
createBuffer: () => HarfBuzzBuffer;
|
|
60
|
+
shape: (font: HarfBuzzFont, buffer: HarfBuzzBuffer) => void;
|
|
61
|
+
}
|
|
62
|
+
interface HarfBuzzBlob {
|
|
63
|
+
destroy: () => void;
|
|
64
|
+
}
|
|
65
|
+
interface HarfBuzzFace {
|
|
66
|
+
destroy: () => void;
|
|
67
|
+
getAxisInfos: () => {
|
|
68
|
+
[tag: string]: VariationAxis;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
interface HarfBuzzFont {
|
|
72
|
+
ptr: number;
|
|
73
|
+
destroy: () => void;
|
|
74
|
+
setScale: (xScale: number, yScale: number) => void;
|
|
75
|
+
setVariations: (variations: {
|
|
76
|
+
[key: string]: number;
|
|
77
|
+
}) => void;
|
|
78
|
+
}
|
|
79
|
+
interface HarfBuzzBuffer {
|
|
80
|
+
addText: (text: string) => void;
|
|
81
|
+
guessSegmentProperties: () => void;
|
|
82
|
+
setDirection: (direction: string) => void;
|
|
83
|
+
json: (font: HarfBuzzFont) => any[];
|
|
84
|
+
destroy: () => void;
|
|
85
|
+
}
|
|
86
|
+
interface HarfBuzzInstance {
|
|
87
|
+
hb: HarfBuzzAPI;
|
|
88
|
+
module: HarfBuzzModule;
|
|
89
|
+
}
|
|
90
|
+
interface ExtractedMetrics {
|
|
91
|
+
isCFF: boolean;
|
|
92
|
+
unitsPerEm: number;
|
|
93
|
+
hheaAscender: number | null;
|
|
94
|
+
hheaDescender: number | null;
|
|
95
|
+
hheaLineGap: number | null;
|
|
96
|
+
typoAscender: number | null;
|
|
97
|
+
typoDescender: number | null;
|
|
98
|
+
typoLineGap: number | null;
|
|
99
|
+
winAscent: number | null;
|
|
100
|
+
winDescent: number | null;
|
|
101
|
+
axisNames: {
|
|
102
|
+
[tag: string]: string;
|
|
103
|
+
} | null;
|
|
104
|
+
}
|
|
105
|
+
interface FontMetrics {
|
|
106
|
+
ascender: number;
|
|
107
|
+
descender: number;
|
|
108
|
+
lineGap: number;
|
|
109
|
+
unitsPerEm: number;
|
|
110
|
+
naturalLineHeight: number;
|
|
111
|
+
}
|
|
112
|
+
interface PathInfo {
|
|
113
|
+
start: number;
|
|
114
|
+
count: number;
|
|
115
|
+
}
|
|
116
|
+
interface GlyphGeometryInfo {
|
|
117
|
+
textIndex: number;
|
|
118
|
+
lineIndex: number;
|
|
119
|
+
vertexStart: number;
|
|
120
|
+
vertexCount: number;
|
|
121
|
+
bounds: {
|
|
122
|
+
min: {
|
|
123
|
+
x: number;
|
|
124
|
+
y: number;
|
|
125
|
+
z: number;
|
|
126
|
+
};
|
|
127
|
+
max: {
|
|
128
|
+
x: number;
|
|
129
|
+
y: number;
|
|
130
|
+
z: number;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
paths?: PathInfo[];
|
|
134
|
+
}
|
|
135
|
+
interface TextRange {
|
|
136
|
+
start: number;
|
|
137
|
+
end: number;
|
|
138
|
+
originalText: string;
|
|
139
|
+
bounds: {
|
|
140
|
+
min: {
|
|
141
|
+
x: number;
|
|
142
|
+
y: number;
|
|
143
|
+
z: number;
|
|
144
|
+
};
|
|
145
|
+
max: {
|
|
146
|
+
x: number;
|
|
147
|
+
y: number;
|
|
148
|
+
z: number;
|
|
149
|
+
};
|
|
150
|
+
}[];
|
|
151
|
+
glyphs: GlyphGeometryInfo[];
|
|
152
|
+
lineIndices: number[];
|
|
153
|
+
}
|
|
154
|
+
interface TextQueryOptions {
|
|
155
|
+
byText?: string[];
|
|
156
|
+
byCharRange?: {
|
|
157
|
+
start: number;
|
|
158
|
+
end: number;
|
|
159
|
+
}[];
|
|
160
|
+
}
|
|
161
|
+
interface TextGeometryInfo {
|
|
162
|
+
vertices: Float32Array;
|
|
163
|
+
normals: Float32Array;
|
|
164
|
+
indices: Uint32Array;
|
|
165
|
+
colors?: Float32Array;
|
|
166
|
+
glyphAttributes?: {
|
|
167
|
+
glyphCenter: Float32Array;
|
|
168
|
+
glyphIndex: Float32Array;
|
|
169
|
+
glyphLineIndex: Float32Array;
|
|
170
|
+
};
|
|
171
|
+
glyphs: GlyphGeometryInfo[];
|
|
172
|
+
planeBounds: BoundingBox;
|
|
173
|
+
stats: {
|
|
174
|
+
trianglesGenerated: number;
|
|
175
|
+
verticesGenerated: number;
|
|
176
|
+
pointsRemovedByVisvalingam: number;
|
|
177
|
+
pointsRemovedByColinear: number;
|
|
178
|
+
originalPointCount: number;
|
|
179
|
+
};
|
|
180
|
+
query(options: TextQueryOptions): TextRange[];
|
|
181
|
+
coloredRanges?: ColoredRange[];
|
|
182
|
+
}
|
|
183
|
+
interface ColorByRange {
|
|
184
|
+
start: number;
|
|
185
|
+
end: number;
|
|
186
|
+
color: [number, number, number];
|
|
187
|
+
}
|
|
188
|
+
interface ColorOptions {
|
|
189
|
+
default?: [number, number, number];
|
|
190
|
+
byText?: {
|
|
191
|
+
[text: string]: [number, number, number];
|
|
192
|
+
};
|
|
193
|
+
byCharRange?: ColorByRange[];
|
|
194
|
+
}
|
|
195
|
+
interface ColoredRange {
|
|
196
|
+
start: number;
|
|
197
|
+
end: number;
|
|
198
|
+
originalText: string;
|
|
199
|
+
color: [number, number, number];
|
|
200
|
+
bounds: {
|
|
201
|
+
min: {
|
|
202
|
+
x: number;
|
|
203
|
+
y: number;
|
|
204
|
+
z: number;
|
|
205
|
+
};
|
|
206
|
+
max: {
|
|
207
|
+
x: number;
|
|
208
|
+
y: number;
|
|
209
|
+
z: number;
|
|
210
|
+
};
|
|
211
|
+
}[];
|
|
212
|
+
glyphs: GlyphGeometryInfo[];
|
|
213
|
+
lineIndices: number[];
|
|
214
|
+
}
|
|
215
|
+
interface TextOptions {
|
|
216
|
+
text: string;
|
|
217
|
+
font?: string | ArrayBuffer;
|
|
218
|
+
size?: number;
|
|
219
|
+
depth?: number;
|
|
220
|
+
lineHeight?: number;
|
|
221
|
+
letterSpacing?: number;
|
|
222
|
+
separateGlyphsWithAttributes?: boolean;
|
|
223
|
+
fontVariations?: {
|
|
224
|
+
[key: string]: number;
|
|
225
|
+
};
|
|
226
|
+
maxTextLength?: number;
|
|
227
|
+
removeOverlaps?: boolean;
|
|
228
|
+
curveFidelity?: CurveFidelityConfig;
|
|
229
|
+
geometryOptimization?: GeometryOptimizationOptions;
|
|
230
|
+
layout?: LayoutOptions;
|
|
231
|
+
color?: [number, number, number] | ColorOptions;
|
|
232
|
+
maxCacheSizeMB?: number;
|
|
233
|
+
}
|
|
234
|
+
interface HyphenationPatternsMap {
|
|
235
|
+
[language: string]: HyphenationTrieNode;
|
|
236
|
+
}
|
|
237
|
+
interface CurveFidelityConfig {
|
|
238
|
+
distanceTolerance?: number;
|
|
239
|
+
angleTolerance?: number;
|
|
240
|
+
}
|
|
241
|
+
interface GeometryOptimizationOptions {
|
|
242
|
+
enabled?: boolean;
|
|
243
|
+
areaThreshold?: number;
|
|
244
|
+
colinearThreshold?: number;
|
|
245
|
+
minSegmentLength?: number;
|
|
246
|
+
}
|
|
247
|
+
interface LayoutOptions {
|
|
248
|
+
width?: number;
|
|
249
|
+
align?: TextAlign;
|
|
250
|
+
direction?: TextDirection;
|
|
251
|
+
respectExistingBreaks?: boolean;
|
|
252
|
+
hyphenate?: boolean;
|
|
253
|
+
language?: string;
|
|
254
|
+
patternsPath?: string;
|
|
255
|
+
tolerance?: number;
|
|
256
|
+
pretolerance?: number;
|
|
257
|
+
emergencyStretch?: number;
|
|
258
|
+
autoEmergencyStretch?: number;
|
|
259
|
+
hyphenationPatterns?: HyphenationPatternsMap;
|
|
260
|
+
lefthyphenmin?: number;
|
|
261
|
+
righthyphenmin?: number;
|
|
262
|
+
linepenalty?: number;
|
|
263
|
+
adjdemerits?: number;
|
|
264
|
+
hyphenpenalty?: number;
|
|
265
|
+
exhyphenpenalty?: number;
|
|
266
|
+
doublehyphendemerits?: number;
|
|
267
|
+
looseness?: number;
|
|
268
|
+
disableSingleWordDetection?: boolean;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
interface GlyphCacheStats {
|
|
272
|
+
hits: number;
|
|
273
|
+
misses: number;
|
|
274
|
+
totalGlyphs: number;
|
|
275
|
+
uniqueGlyphs: number;
|
|
276
|
+
cacheSize: number;
|
|
277
|
+
saved: number;
|
|
278
|
+
memoryUsage: number;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
declare global {
|
|
282
|
+
interface Window {
|
|
283
|
+
hbjs?: any;
|
|
284
|
+
createHarfBuzz?: () => Promise<any>;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
declare class Text$1 {
|
|
288
|
+
private static patternCache;
|
|
289
|
+
private static hbInitPromise;
|
|
290
|
+
private static fontCache;
|
|
291
|
+
private static fontIdCounter;
|
|
292
|
+
private fontLoader;
|
|
293
|
+
private loadedFont?;
|
|
294
|
+
private currentFontId;
|
|
295
|
+
private geometryBuilder?;
|
|
296
|
+
private textShaper?;
|
|
297
|
+
private textLayout?;
|
|
298
|
+
private constructor();
|
|
299
|
+
static setHarfBuzzPath(path: string): void;
|
|
300
|
+
static setHarfBuzzBuffer(wasmBuffer: ArrayBuffer): void;
|
|
301
|
+
static init(): Promise<HarfBuzzInstance>;
|
|
302
|
+
static create(options: TextOptions): Promise<TextGeometryInfo & Pick<Text$1, 'getLoadedFont' | 'getCacheStatistics' | 'clearCache' | 'measureTextWidth'>>;
|
|
303
|
+
private static loadAndCacheFont;
|
|
304
|
+
private static generateFontContentHash;
|
|
305
|
+
private setLoadedFont;
|
|
306
|
+
private loadFont;
|
|
307
|
+
private createGeometry;
|
|
308
|
+
private prepareHyphenation;
|
|
309
|
+
private validateOptions;
|
|
310
|
+
private updateFontVariations;
|
|
311
|
+
private prepareLayout;
|
|
312
|
+
private applyColorSystem;
|
|
313
|
+
private finalizeGeometry;
|
|
314
|
+
getFontMetrics(): FontMetrics;
|
|
315
|
+
static preloadPatterns(languages: string[], patternsPath?: string): Promise<void>;
|
|
316
|
+
static registerPattern(language: string, pattern: HyphenationTrieNode): void;
|
|
317
|
+
getLoadedFont(): LoadedFont | undefined;
|
|
318
|
+
measureTextWidth(text: string, letterSpacing?: number): number;
|
|
319
|
+
getCacheStatistics(): GlyphCacheStats | null;
|
|
320
|
+
clearCache(): void;
|
|
321
|
+
private createGlyphAttributes;
|
|
322
|
+
destroy(): void;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
interface ThreeTextProps extends Omit<TextOptions$1, "text"> {
|
|
326
|
+
children: string;
|
|
327
|
+
font: string | ArrayBuffer;
|
|
328
|
+
material?: THREE.Material;
|
|
329
|
+
position?: [number, number, number];
|
|
330
|
+
rotation?: [number, number, number];
|
|
331
|
+
scale?: [number, number, number];
|
|
332
|
+
onLoad?: (geometry: THREE.BufferGeometry, info: ThreeTextGeometryInfo) => void;
|
|
333
|
+
onError?: (error: Error) => void;
|
|
334
|
+
vertexColors?: boolean;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
declare const Text: react.ForwardRefExoticComponent<ThreeTextProps & react.RefAttributes<THREE.Mesh<THREE.BufferGeometry<THREE.NormalBufferAttributes, THREE.BufferGeometryEventMap>, THREE.Material | THREE.Material[], THREE.Object3DEventMap>>> & {
|
|
338
|
+
setHarfBuzzPath: typeof Text$1.setHarfBuzzPath;
|
|
339
|
+
setHarfBuzzBuffer: typeof Text$1.setHarfBuzzBuffer;
|
|
340
|
+
init: typeof Text$1.init;
|
|
341
|
+
registerPattern: typeof Text$1.registerPattern;
|
|
342
|
+
preloadPatterns: typeof Text$1.preloadPatterns;
|
|
343
|
+
create: typeof Text$2.create;
|
|
344
|
+
};
|
|
345
|
+
|
|
346
|
+
export { Text, ThreeTextProps };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
2
|
import { forwardRef, useState, useMemo, useEffect, useRef } from 'react';
|
|
3
3
|
import * as THREE from 'three';
|
|
4
|
-
import { Text } from '
|
|
4
|
+
import { Text as Text$2 } from './index';
|
|
5
5
|
|
|
6
6
|
function deepEqual(a, b) {
|
|
7
7
|
if (a === b)
|
|
@@ -29,7 +29,7 @@ function useDeepCompareMemo(value) {
|
|
|
29
29
|
}
|
|
30
30
|
return ref.current;
|
|
31
31
|
}
|
|
32
|
-
const
|
|
32
|
+
const Text$1 = forwardRef(function Text(props, ref) {
|
|
33
33
|
const { children, font, material, position = [0, 0, 0], rotation = [0, 0, 0], scale = [1, 1, 1], onLoad, onError, vertexColors = true, ...restOptions } = props;
|
|
34
34
|
const [geometry, setGeometry] = useState(null);
|
|
35
35
|
const [error, setError] = useState(null);
|
|
@@ -46,7 +46,7 @@ const ThreeText = forwardRef(function ThreeText(props, ref) {
|
|
|
46
46
|
setError(null);
|
|
47
47
|
if (cancelled)
|
|
48
48
|
return;
|
|
49
|
-
const text = await Text.create({
|
|
49
|
+
const text = await Text$2.create({
|
|
50
50
|
text: children,
|
|
51
51
|
font,
|
|
52
52
|
...memoizedTextOptions,
|
|
@@ -97,4 +97,14 @@ const ThreeText = forwardRef(function ThreeText(props, ref) {
|
|
|
97
97
|
return (jsx("mesh", { ref: ref, geometry: geometry, material: finalMaterial, position: position, rotation: rotation, scale: scale }));
|
|
98
98
|
});
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
// Attach static methods from ThreeText to the React component
|
|
101
|
+
const Text = Object.assign(Text$1, {
|
|
102
|
+
setHarfBuzzPath: Text$2.setHarfBuzzPath,
|
|
103
|
+
setHarfBuzzBuffer: Text$2.setHarfBuzzBuffer,
|
|
104
|
+
init: Text$2.init,
|
|
105
|
+
registerPattern: Text$2.registerPattern,
|
|
106
|
+
preloadPatterns: Text$2.preloadPatterns,
|
|
107
|
+
create: Text$2.create
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
export { Text };
|
|
@@ -40,6 +40,6 @@ export declare class Text {
|
|
|
40
40
|
measureTextWidth(text: string, letterSpacing?: number): number;
|
|
41
41
|
getCacheStatistics(): import("./cache/GlyphCache").GlyphCacheStats | null;
|
|
42
42
|
clearCache(): void;
|
|
43
|
-
private
|
|
43
|
+
private createGlyphAttributes;
|
|
44
44
|
destroy(): void;
|
|
45
45
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Vec3 } from '../vectors';
|
|
2
2
|
import { ProcessedGeometry } from '../types';
|
|
3
3
|
export interface GlyphData {
|
|
4
4
|
geometry: ProcessedGeometry;
|
|
@@ -6,14 +6,14 @@ export interface GlyphData {
|
|
|
6
6
|
normals: Float32Array;
|
|
7
7
|
indices: Uint16Array | Uint32Array;
|
|
8
8
|
bounds: {
|
|
9
|
-
min:
|
|
10
|
-
max:
|
|
9
|
+
min: Vec3;
|
|
10
|
+
max: Vec3;
|
|
11
11
|
};
|
|
12
12
|
useCount: number;
|
|
13
13
|
}
|
|
14
14
|
export interface GlyphInstance {
|
|
15
15
|
glyphId: number;
|
|
16
|
-
position:
|
|
16
|
+
position: Vec3;
|
|
17
17
|
scale: number;
|
|
18
18
|
textIndex: number;
|
|
19
19
|
lineIndex: number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Vec2 } from '../vectors';
|
|
2
2
|
import { GlyphContours } from '../types';
|
|
3
3
|
import { OptimizationStats } from '../geometry/PathOptimizer';
|
|
4
4
|
import { CurveFidelityConfig, GeometryOptimizationOptions } from '../types';
|
|
@@ -28,7 +28,7 @@ export declare class GlyphContourCollector {
|
|
|
28
28
|
private finishPath;
|
|
29
29
|
private updateBounds;
|
|
30
30
|
getCollectedGlyphs(): GlyphContours[];
|
|
31
|
-
getGlyphPositions():
|
|
31
|
+
getGlyphPositions(): Vec2[];
|
|
32
32
|
getTextIndices(): number[];
|
|
33
33
|
reset(): void;
|
|
34
34
|
setCurveFidelityConfig(config?: CurveFidelityConfig): void;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { BufferGeometry } from 'three';
|
|
2
1
|
import { GlyphCache } from './GlyphCache';
|
|
3
2
|
import { GlyphGeometryInfo, LoadedFont, GlyphCluster } from '../types';
|
|
4
3
|
import { CurveFidelityConfig, GeometryOptimizationOptions } from '../types';
|
|
5
4
|
export interface InstancedTextGeometry {
|
|
6
|
-
|
|
5
|
+
vertices: Float32Array;
|
|
6
|
+
normals: Float32Array;
|
|
7
|
+
indices: Uint32Array;
|
|
7
8
|
glyphInfos: GlyphGeometryInfo[];
|
|
8
9
|
planeBounds: {
|
|
9
10
|
min: {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Vec3 } from '../vectors';
|
|
2
2
|
import type { GlyphContours } from '../types';
|
|
3
3
|
export declare class BoundaryClusterer {
|
|
4
4
|
constructor();
|
|
5
|
-
cluster(glyphContoursList: GlyphContours[], positions:
|
|
5
|
+
cluster(glyphContoursList: GlyphContours[], positions: Vec3[]): number[][];
|
|
6
6
|
private clusterSweepLine;
|
|
7
7
|
private getWorldBounds;
|
|
8
8
|
}
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
36
36
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
37
37
|
*/
|
|
38
|
-
import {
|
|
38
|
+
import { Vec2 } from '../vectors';
|
|
39
39
|
import { CurveFidelityConfig } from '../types';
|
|
40
40
|
export declare const DEFAULT_CURVE_FIDELITY: CurveFidelityConfig;
|
|
41
41
|
export declare const COLLINEARITY_EPSILON = 0.000001;
|
|
@@ -43,8 +43,8 @@ export declare class Polygonizer {
|
|
|
43
43
|
private curveFidelityConfig;
|
|
44
44
|
constructor(curveFidelityConfig?: CurveFidelityConfig);
|
|
45
45
|
setCurveFidelityConfig(curveFidelityConfig?: CurveFidelityConfig): void;
|
|
46
|
-
polygonizeQuadratic(start:
|
|
47
|
-
polygonizeCubic(start:
|
|
46
|
+
polygonizeQuadratic(start: Vec2, control: Vec2, end: Vec2): Vec2[];
|
|
47
|
+
polygonizeCubic(start: Vec2, control1: Vec2, control2: Vec2, end: Vec2): Vec2[];
|
|
48
48
|
private recursiveQuadratic;
|
|
49
49
|
private recursiveCubic;
|
|
50
50
|
private addPoint;
|